十二.Spring Boot整合webSocket

一.项目创建

在这里插入图片描述

二.代码

  • 配置文件
    WebSocketConfig
package com.miracle.websocket.config;

import com.miracle.websocket.handler.TextMessageHandler;
import com.miracle.websocket.interceptor.WebSocketInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Configuration      // 配置类
@EnableWebSocket    // 启用webSocket      // 实现 WebSocketConfigurer
public class WebSocketConfig implements WebSocketConfigurer {

    /**
     * 注册webSocket处理类
     * @param webSocketHandlerRegistry
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        /*
            webSocketHandler:       webSocket处理逻辑,单例的
            strings:                拦截路径
            handShakeInterceptor:   拦截器,用来记录请求 和 session 之间的对应关系,多例
         */
        webSocketHandlerRegistry.addHandler(socketHandler(), "/websocket/*").addInterceptors(new WebSocketInterceptor());
    }

    @Bean
    public TextWebSocketHandler socketHandler(){
        return new TextMessageHandler();
    }
}
  • 拦截器
package com.miracle.websocket.interceptor;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import java.util.Map;

public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
    /**
     * webSocket捂手拦截器,检查捂手请求和响应,对webSocketHandler传递属性,用于区别WebSocket
     * @param request
     * @param response
     * @param wsHandler
     * @param attributes
     * @return
     * @throws Exception
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 这里为了区分webSocket连接,可以通过名字区分(前台发送webSocket,需要携带名字)
        // 这里约定请求为rest形式请求,最后一个路径参数为名字
        // 请求url
        String url = request.getURI().toString();
        // name
        String name = url.substring(url.lastIndexOf("/") + 1);
        // 设置名字
        attributes.put("name", name);
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {

    }
}
  • 处理器
package com.miracle.websocket.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.HashMap;
import java.util.Map;

public class TextMessageHandler extends TextWebSocketHandler {

    private Map<String,WebSocketSession> allClient = new HashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 获取在拦截器中设置的name
        String name = (String) session.getAttributes().get("name");
        if (name != null){
            // 保存当前用户和连接的关系
            allClient.put(name, session);
        }
    }

    /**
     *
     * @param session       当前发送消息的用户连接
     * @param message       发送的消息是什么
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, String> jsonMap = objectMapper.readValue(new String(message.asBytes()), Map.class);
        // 消息接收者
        String toUser = jsonMap.get("toUser");
        // 要发送的消息
        String toMessage = jsonMap.get("toMessage");
        String fromUser = (String)session.getAttributes().get("name");

        String content = "收到来自" + fromUser + "的消息,内容是:" + toMessage;

        TextMessage textMessage = new TextMessage(content);

        WebSocketSession toSession = allClient.get(toUser);
        if (toMessage != null && session.isOpen()){
            toSession.sendMessage(textMessage);
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
    }
}
  • 测试页面
<html>
<head>
    <meta charset="UTF-8">
    <script type="text/javascript">
        var webSocket = null;
        function connection() {
            var username = document.getElementById("name").value;
            // 判断浏览器是否支持websocket
            if ('WebSocket' in window){
                webSocket = new WebSocket("ws://" + document.location.host + "/websocket/" + username);
            }else {
                alert('不支持Websocket')
            }
            webSocket.onopen = function () {
                document.getElementById("message").innerHTML = "建立连接了";
            };
            webSocket.onmessage = function (event) {
                var data = event.data;
                document.getElementById("message").innerHTML = "收到消息了:" + data;
            };
            webSocket.onerror = function () {
                document.getElementById("message").innerHTML = "出现异常了";
            };
            webSocket.onclose = function () {
                document.getElementById("message").innerHTML = "连接关闭了";
            };

            // 当浏览器的页面窗口关闭的时候,此处应该关闭连接,释放服务器资源
            window.onbeforeunload = function (event) {
                if (webSocket != null){
                    webSocket.close();
                }
            }
        };
        function sendMessage(){
            var toUser = document.getElementById("toUser").value;
            var toMessage = document.getElementById("toMessage").value;
            if(webSocket != null){
                var message = '{"toUser":"' + toUser + '","toMessage":"' + toMessage + '"}';
                webSocket.send(message);
            }
        }
    </script>
</head>
<body>
    <input type="text" id="name" name="name">
    <button onclick="connection()">连接</button>
    <br>

    接收者名字:<input type="text" name="toUser" id="toUser"><br>
    内容:<input type="text" name="toMessage" id="toMessage"><br>
    <button onclick="sendMessage()">发送</button>

    <h2 id="message">Hello World!</h2>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值