1.添加依赖:在pom.xml
文件中添加WebSocket相关依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.创建WebSocket配置类:创建一个WebSocket配置类,用于配置WebSocket端点和处理器。
@Configuration
@EnableWebSocket
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpoint(){return new ServerEndpointExporter();}
}
3.创建WebSocket处理器:创建一个WebSocket处理器,用于处理WebSocket连接和消息。
@Component
@ServerEndpoint("/chat")
public class ChatService {/*** 连接会话池*/private static ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<>();@OnOpenpublic void onOpen(Session session) throws IOException {// 判断客户端对象是否存在if (SESSION_POOL.containsKey(session.getQueryString())) {CloseReason closeReason = new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "ID冲突,连接拒绝");session.getUserProperties().put("reason", closeReason);session.close();return;}// 将客户端对象存储到会话池SESSION_POOL.put(session.getQueryString(), session);System.out.println("客户端(" + session.getQueryString() + "):开启了连接");}@OnMessagepublic String onMessage(String msg, Session session) throws IOException {// 解析消息 ==> ID::消息内容String[] msgArr = msg.split("::", 2);// 处理群发消息,ID==all表示群发if ("all".equalsIgnoreCase(msgArr[0])) {for (Session one : SESSION_POOL.values()) {// 排除自己if (one == session) {continue;}// 发送消息one.getBasicRemote().sendText(msgArr[1]);}}// 指定发送else {// 获取接收方Session target = SESSION_POOL.get(msgArr[0]);if (target != null) {target.getBasicRemote().sendText(msgArr[1]);}}return session.getQueryString() + ":消息发送成功";}@OnClosepublic void onClose(Session session) {// 连接拒绝关闭会话Object reason = session.getUserProperties().get("reason");if (reason instanceof CloseReason) {CloseReason creason = (CloseReason) reason;if (creason.getCloseCode() == CloseReason.CloseCodes.CANNOT_ACCEPT) {System.out.println("拒绝客户(" + session.getQueryString() + "):关闭连接");return;}}// 从会话池中移除会话SESSION_POOL.remove(session.getQueryString());System.out.println("客户端(" + session.getQueryString() + "):关闭连接");}@OnErrorpublic void onError(Session session, Throwable throwable) {System.out.println("客户端(" + session.getQueryString() + ")错误信息:" + throwable.getMessage());}@SneakyThrowspublic void sendMessage(String id, Object message) {// 群发if ("all".equalsIgnoreCase(id)) {for (Session one : SESSION_POOL.values()) {// 发送消息one.getBasicRemote().sendText(JSONUtil.toJsonStr(message));}}// 指定发送else {// 获取接收方Session target = SESSION_POOL.get(id);if (target != null) {target.getBasicRemote().sendText(JSONUtil.toJsonStr(message));}}}
}
4.创建HTML页面:创建一个HTML页面,用于在浏览器中连接WebSocket并进行聊天。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>聊天室客户端</title>
</head>
<body>
<h1>Chat Client</h1>
<div><input id="clientId" placeholder="输入ID" value="1"><input onclick="init()" value="连接服务器" type="button"><br><br><input id="receiverId" placeholder="输入接收人ID" value="all"><br><br><textarea id="message" style="margin: 0; height: 197px; width: 362px;"placeholder="发送消息内容"></textarea><br><input onclick="send()" value="发送消息" type="button"><input onclick="closeConnect()" value="关闭连接" type="button">
</div>
<div id="output"></div>
<script type="text/javascript" language="JavaScript">//屏幕回显输出方法function writeToScreen(message) {let pre = document.createElement("p");pre.style.wordWrap = "break-word";pre.innerHTML = message;document.getElementById("output").appendChild(pre);}//初始化websocketlet echo_websocket;function init() {let clientId = document.getElementById("clientId").value;let wsUri = "ws://localhost:10500/chat?" + clientId;writeToScreen("连接到" + wsUri);//1.创建WebSocket客户端对象echo_websocket = new WebSocket(wsUri);//2.开门握手完成回调echo_websocket.onopen = function (evt) {console.log(evt);writeToScreen("连接打开成功 !");};//3.监听服务端的消息echo_websocket.onmessage = function (evt) {writeToScreen("接收服务端消息:<br> " + evt.data);};//4.如果连接中断echo_websocket.onerror = function (evt) {writeToScreen('<span style="color: red;">ERROR:'+evt.data+'</span>');//关闭连接closeConnect();};//5.注册close事件echo_websocket.onclose = function(evt){writeToScreen('<span style="color: green;">INFO:关闭连接</span> ');if(evt.reason){writeToScreen(`<span style="color: red;">错误信息:${evt.reason}</span> `);}}}//6.向服务发送消息function send() {let message = document.getElementById("message").value;let receiver = document.getElementById("receiverId").value;echo_websocket.send(receiver + "::" + message);writeToScreen("发送消息: " + message);}//7.如果不需要通讯,那么关闭连接function closeConnect() {echo_websocket.close();}
</script>
</body>
</html>