1、pom.xml引入jar
<!-- 引入websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、创建WebSocket配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、创建WebSocket服务
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Component
@ServerEndpoint("/socketServer/{uid}")
@Slf4j
public class WebSocketServer {
private static UserService userService;
// @Autowired只能在set方法注入,不然会null报错
@Autowired
public void setUserService(UserService userService) {
WebSocketServer.userService = userService;
}
/**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。这里暂不做考虑*/
private static int onlineCount = 0;
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据.
*/
private Session session;
/**
* 接收客户端消息的uid
*/
private String uid = "";
/**
* concurrent包是线程安全的Set,用来存放每个客户端对应的WebSocket对象。
*/
private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("uid") String uid) {
log.info("用户连接建立成功:"+uid);
this.session = session;
this.uid = uid;
if (webSocketMap.containsKey(uid)) {
webSocketMap.remove(uid);
//加入到set中
webSocketMap.put(uid, this);
} else {
//加入set中
webSocketMap.put(uid, this);
//加入set中
addOnlineCount();
//在线数加1
}
try {
sendMsg("{\"status\": \"加入成功\"}");
} catch (IOException e) {
log.error("用户:" + uid + ",网络异常!!!!!!");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if (webSocketMap.containsKey(uid)) {
webSocketMap.remove(uid);
//从set中删除
subOnlineCount();
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message) {
log.info("收到用户消息:"+uid+",报文:"+message);
try {
// 给uid发送消息
webSocketMap.get(uid).sendMsg(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 处理错误
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误:" + this.uid + ",原因:" + error.getMessage());
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
private void sendMsg(String msg) throws IOException {
this.session.getBasicRemote().sendText(msg);
}
private static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
private static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
4、可以自己创建一个测试页面链接websocket地址:
ws://localhost:8080/socketServer/40
<!DOCTYPE HTML>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>websocket测试</title>
<script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
alert("您的浏览器支持 WebSocket!");
// 打开一个 web socket
var ws = new WebSocket("ws://localhost:8080/socketServer/40");
ws.onopen = function()
{
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
alert("数据发送中...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert("数据已接收...");
console.log(evt.data)
};
ws.onclose = function()
{
// 关闭 websocket
alert("连接已关闭...");
};
}
else
{
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
</script>
</head>
<body>
<div id="sse">
<a href="javascript:WebSocketTest()">点击测试连接 WebSocket</a>
</div>
</body>
</html>