Spring Boot ---websocket

赖淇
2023-12-01

Spring Boot —websocket

首先导入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>

  1. html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script>
        $(function(){
        //发送消息
            $("#send").click(function(){
                console.log("send....")
                if(typeof(WebSocket) == "undefined") {
                    console.log("您的浏览器不支持WebSocket");
                }else {
                    console.log("您的浏览器支持WebSocket");
                    console.log('{"all":1,"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');
                    socket.send('{"all":1,"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');
                }
            })
            //进入链接
            $("#go").click(function(){
                if(typeof(WebSocket) == "undefined") {
                    console.log("您的浏览器不支持WebSocket");
                }else {
                    console.log("您的浏览器支持WebSocket");
                    //创建ws链接,根据输入的userid
                    var socketUrl = "http://localhost:8080/demo/" + $("#userid").val();
                    socketUrl = socketUrl.replace("https", "ws").replace("http", "ws");
                    console.log(socketUrl);
                    socket = new WebSocket(socketUrl);
                    //根据服务器返回异步的打开事件
                    socket.onopen = function () {
                        console.log("websocket已打开");
                        //socket.send("这是来自客户端的消息" + location.href + new Date());
                    };
                    //根据服务器返回异步的获得消息事件
                    socket.onmessage = function(msg) {
                        //获取到发送的消息
                        var a = JSON.stringify(msg);
                        console.log(a);
                    };
                }
            });
        })
    </script>
</head>
<body>
输入用户名:<input type="text" id="userid">
<button id="go">进入</button>
选择发送人:<input type="text" id="toUserId">
发送的内容:<input type="text" id="contentText">

<button id="send">发送消息</button>
</body>
  1. 需要配置一个websocket的配置类
/**
 * 开启WebSocket支持
 * 
 */
@Configuration
public class MyWebSocket {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
}

3.再创建一个controller类用户接受用户登录以及发送消息

//使用@ServerEndpoint注解来设置哪个链接来处理websocket
@ServerEndpoint("/demo/{userId}")
@Component
public class WebSocketServer {
        /**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/
        private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
        /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
        private Session session;
        /**接收userId*/
        private String userId="";
    /*** 连接建立成功调用的方法*/
        @OnOpen
        public void onOpen(Session session, @PathParam("userId") String userId) {
            this.session = session;
            this.userId=userId;
            if(webSocketMap.containsKey(userId)){
                webSocketMap.remove(userId);
                webSocketMap.put(userId,this);
                //加入set中
            }else{
                webSocketMap.put(userId,this);
                //加入set中
            }
            System.out.println("用户连接:"+userId+"---"+session );
        }
    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("用户消息:"+userId+",报文:"+message);
        //可以群发消息
        //消息保存到数据库、redis
        if(StringUtils.isNotBlank(message)){
            try {
                //将message转化json
                JSONObject jsonObject = JSON.parseObject(message);
                //追加发送人(防止串改)
                jsonObject.put("fromUserId",this.userId);
                String toUserId=jsonObject.getString("toUserId");
                String all = jsonObject.getString("all");
                if(all.equals("1")){
                    System.out.println("qunfa");
                    //ConcurrentHashMap<String,WebSocketServer> webSocketMap
                    for(Map.Entry<String,WebSocketServer> entry : webSocketMap.entrySet()){
                        //获取到所有map中的链接, 然后发送消息 并是用多线程
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    entry.getValue().sendMessage(jsonObject.toJSONString());
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                            }
                        }).start();

                    }
                }else{
                    //传送给对应toUserId用户的websocket
                    if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){
                        System.out.println("向"+toUserId+"发送"+message);
                        webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
                    }else{
                        System.out.println("请求的userId:"+toUserId+"不在该服务器上");
                        //否则不在这个服务器上,发送到mysql或者redis
                    }
                }
                } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
    /**
     * 连接关闭调用的方法
     * 前端浏览器关闭时
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
        }
        System.out.println("用户退出:"+userId);
    }
    /**
     * 发送消息方法
     */
    public  void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


}

相关文章https://blog.csdn.net/moshowgame/article/details/80275084

 类似资料: