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 {
- @Bean
- public ServerEndpointExporter serverEndpoint(){
- return new ServerEndpointExporter();
- }
- }
3.创建WebSocket处理器:创建一个WebSocket处理器,用于处理WebSocket连接和消息。
- @Component
- @ServerEndpoint("/chat")
- public class ChatService {
- /**
- * 连接会话池
- */
- private static ConcurrentHashMap
SESSION_POOL = new ConcurrentHashMap<>(); -
- @OnOpen
- public 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() + "):开启了连接");
- }
-
- @OnMessage
- public 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() + ":消息发送成功";
- }
-
- @OnClose
- public 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() + "):关闭连接");
- }
-
- @OnError
- public void onError(Session session, Throwable throwable) {
- System.out.println("客户端(" + session.getQueryString() + ")错误信息:" + throwable.getMessage());
- }
-
- @SneakyThrows
- public 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并进行聊天。
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>聊天室客户端title>
- head>
- <body>
- <h1>Chat Clienth1>
- <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);
- }
-
- //初始化websocket
- let 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("接收服务端消息:
" + evt.data); - };
- //4.如果连接中断
- echo_websocket.onerror = function (evt) {
- writeToScreen('ERROR:'+evt.data+'');
- //关闭连接
- closeConnect();
- };
- //5.注册close事件
- echo_websocket.onclose = function(evt){
- writeToScreen('INFO:关闭连接 ');
- if(evt.reason){
- writeToScreen
- (`错误信息:${evt.reason} `);
- }
- }
- }
-
- //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>