pom
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* websocket
* @author : liuyuhang
* @date 2022/4/19
*/
@Configuration
public class WebSocketConfiguration {
/**
* 扫描并注册带有@ServerEndpoint注解的所有服务端
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
server
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 订单消息服务
* @author : liuyuhang
* @date 2022/4/19
*/
@Component
@ServerEndpoint("/ws/payment/{uid}")
@Slf4j
public class WebSocketServer {
/** 用来记录当前在线连接数。*/
private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0);
/**
* 接受消息的用户链接{key:uid}
*/
private static final ConcurrentHashMap<String, WebSocketServer> UID_SERVER = new ConcurrentHashMap<>();
/**
* 客户端的连接会话
*/
private Session session;
/**
* 用户ID
*/
private String uid;
/**
* 连接建立成功时触发,绑定参数
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
* @param uid 用户ID
*/
@OnOpen
public void onOpen(Session session, @PathParam("uid") String uid) throws IOException {
this.session = session;
this.uid = uid;
//同样业务的连接已经在线,则把原来的挤下线。
WebSocketServer uidServer = UID_SERVER.get(uid);
if(uidServer != null){
uidServer.session.getBasicRemote().sendText(uid + "重复连接.");
uidServer.session.close();
}
//保存uid对应的连接服务
UID_SERVER.put(uid, this);
addOnlineCount();
}
/**
* 连接关闭
*/
@OnClose
public void onClose() {
UID_SERVER.remove(uid);
reduceOnlineCount();
}
/**
* 收到客户端消息后
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message) {
log.info("收到消息:" + message);
}
/**
* 通信发生错误时触发
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("{}:通信发生错误,连接关闭",uid,error);
UID_SERVER.remove(uid);
}
/**
* 指定用户发送消息
* @param uid 用户ID
* @param message 消息
*/
public void sendMessage(String uid, String message){
WebSocketServer uidServer = UID_SERVER.get(uid);
try {
if (uidServer!=null) {
uidServer.session.getBasicRemote().sendText(message);
}
}catch (Exception e){
log.error(">>>>>>支付成功消息推送异常{},{}",uid,message,e);
}
}
/**
* 获取在线连接数
*/
public static int getOnlineCount() {
return ONLINE_COUNT.get();
}
/**
* 在线连接数加一
*/
public static void addOnlineCount() {
ONLINE_COUNT.getAndIncrement();
}
/**
* 在线连接数减一
*/
public static void reduceOnlineCount() {
ONLINE_COUNT.getAndDecrement();
}
}
使用
json需要自己进行封装。
前端
<html>
<head>
<meta charset="UTF-8">
<title>websocket测试</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<style type="text/css">
h3,h4{
text-align:center;
}
</style>
</head>
<body>
<h3>WebSocket测试,客户端接收到的消息如下:</h3>
<textarea id = "messageId" readonly="readonly" cols="150" rows="30" >
</textarea>
<script type="text/javascript">
var socket;
if (typeof (WebSocket) == "undefined") {
console.log("遗憾:您的浏览器不支持WebSocket");
} else {
console.log("恭喜:您的浏览器支持WebSocket");
//实现化WebSocket对象
//指定要连接的服务器地址与端口建立连接
//注意ws、wss使用不同的端口。我使用自签名的证书测试,
//无法使用wss,浏览器打开WebSocket时报错
//ws对应http、wss对应https。
socket = new WebSocket("ws://localhost:17005/ws/payment/0519");
//连接打开事件
socket.onopen = function() {
console.log("Socket 已打开");
socket.send("消息发送测试(From Client)");
};
//收到消息事件
socket.onmessage = function(msg) {
$("#messageId").append(msg.data+ "\n");
console.log(msg.data );
};
//连接关闭事件
socket.onclose = function() {
console.log("Socket已关闭");
};
//发生了错误事件
socket.onerror = function() {
alert("Socket发生了错误");
}
//窗口关闭时,关闭连接
window.unload=function() {
socket.close();
};
}
</script>
</body>
</html>