• SpringBoot整合websocket


    1、新增pom依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>

    2配置bean

        @Bean
        public ServerEndpointExporter serverEndpointExporter()
        {
            return new ServerEndpointExporter();
        }

    3websocket处理类

    package com.oremouse.websocket;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.ConcurrentHashMap;
    import javax.websocket.OnClose;
    import javax.websocket.OnError;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    
    @Component
    @ServerEndpoint("/websocket/{username}")
    public class WebSocket {
    
        public static Logger logger = LoggerFactory.getLogger(WebSocket.class);
        /**
         * 在线人数
         */
        public static int onlineNumber = 0;
    
        /**
         * 以用户的姓名为key,WebSocket为对象保存起来
         */
        private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
        /**
         * 会话
         */
        private Session session;
        /**
         * 用户名称
         */
        private String username;
    
        /**
         * 建立连接
         *
         * @param session
         */
        @OnOpen
        public void onOpen(@PathParam("username") String username, Session session) {
            logger.info("现在来连接的客户id:" + session.getId() + "用户名:" + username);
            onlineNumber++;
            this.username = username;
            this.session = session;
            logger.info("有新连接加入! 当前在线人数" + onlineNumber);
            try {
                // messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
                // 先给所有人发送通知,说我上线了
                Map<String, Object> map1 = new HashMap<String, Object>();
                map1.put("messageType", 1);
                map1.put("username", username);
                sendMessageAll(JSON.toJSONString(map1), username);
    
                // 把自己的信息加入到map当中去
                clients.put(username, this);
                // 给自己发一条消息:告诉自己现在都有谁在线
                Map<String, Object> map2 = new HashMap<String, Object>();
                map2.put("messageType", 3);
                // 移除掉自己
                Set<String> set = clients.keySet();
                map2.put("onlineUsers", set);
                sendMessageTo(JSON.toJSONString(map2), username);
            } catch (IOException e) {
                logger.info(username + "上线的时候通知所有人发生了错误");
            }
    
        }
    
        @OnError
        public void onError(Session session, Throwable error) {
            logger.info("服务端发生了错误" + error.getMessage());
            // error.printStackTrace();
        }
    
        /**
         * 连接关闭
         */
        @OnClose
        public void onClose() {
            onlineNumber--;
            // webSockets.remove(this);
            clients.remove(username);
            try {
                // messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
                Map<String, Object> map1 = new HashMap<String, Object>();
                map1.put("messageType", 2);
                map1.put("onlineUsers", clients.keySet());
                map1.put("username", username);
                sendMessageAll(JSON.toJSONString(map1), username);
            } catch (IOException e) {
                logger.info(username + "下线的时候通知所有人发生了错误");
            }
            logger.info("有连接关闭! 当前在线人数" + onlineNumber);
        }
    
        /**
         * 收到客户端的消息
         *
         * @param message 消息
         * @param session 会话
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            try {
                logger.info("来自客户端消息:" + message + "客户端的id是:" + session.getId());
                JSONObject jsonObject = JSON.parseObject(message);
                String textMessage = jsonObject.getString("message");
                String fromusername = jsonObject.getString("username");
                String tousername = jsonObject.getString("to");
                // 如果不是发给所有,那么就发给某一个人
                // messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
                Map<String, Object> map1 = new HashMap<String, Object>();
                map1.put("messageType", 4);
                map1.put("textMessage", textMessage);
                map1.put("fromusername", fromusername);
                if (tousername.equals("All")) {
                    map1.put("tousername", "所有人");
                    sendMessageAll(JSON.toJSONString(map1), fromusername);
                } else {
                    map1.put("tousername", tousername);
                    sendMessageTo(JSON.toJSONString(map1), tousername);
                }
            } catch (Exception e) {
                logger.info("发生了错误了");
            }
    
        }
    
        public void sendMessageTo(String message, String ToUserName) throws IOException {
            for (WebSocket item : clients.values()) {
                if (item.username.equals(ToUserName)) {
                    item.session.getAsyncRemote().sendText(message);
                    break;
                }
            }
        }
    
        public void sendMessageAll(String message, String FromUserName) throws IOException {
            for (WebSocket item : clients.values()) {
                item.session.getAsyncRemote().sendText(message);
            }
        }
    
        public static synchronized int getOnlineCount() {
            return onlineNumber;
        }
    
    }

    4、页面跳转controller

         @RequestMapping("/websocket/{name}")
            public String testWebSocket(@PathVariable String name,Model model){
                try{
                    model.addAttribute("username",name);
                    return "websocket";
                }
                catch (Exception e){
                    return "error";
                }
         }

     

    5、页面

    <!DOCTYPE html>
    <html>
    <head>
        <title>websocket</title>
        <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script>
        <script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
        <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
    </head>
     
    <body>
        <br/>
        <div style="margin: auto;text-align: center">
            <select id="onLineUser">
                <option>--所有--</option>
            </select>
            <input id="text" type="text" />
            <button  id="sendMsgBtn"  >发送消息</button>
        </div>
        <br>
        <div style="margin-right: 10px;text-align: right">
            <button id="closeBtn" >关闭连接</button>
        </div>
        <hr/>
        <div id="message" style="text-align: center;"></div>
        <input  type="text" th:value="${username}" id="username" style="display: none" />
    </body>
     
     
    <script type="text/javascript">
        var webSocket;
        var commWebSocket;
        if ("WebSocket" in window)
        {
            webSocket = new WebSocket("ws://localhost:8086/websocket/"+document.getElementById('username').value);
     
            //连通之后的回调事件
            webSocket.onopen = function()
            {
                //webSocket.send( document.getElementById('username').value+"已经上线了");
                console.log("已经连通了websocket");
                setMessageInnerHTML("已经连通了websocket");
            };
     
            //接收后台服务端的消息
            webSocket.onmessage = function (evt)
            {
                var received_msg = evt.data;
                console.log("数据已接收:" +received_msg);
                var obj = JSON.parse(received_msg);
                console.log("可以解析成json:"+obj.messageType);
                //1代表上线 2代表下线 3代表在线名单 4代表普通消息
                if(obj.messageType==1){
                    //把名称放入到selection当中供选择
                    var onlineName = obj.username;
                    var option = "<option>"+onlineName+"</option>";
                    $("#onLineUser").append(option);
                    setMessageInnerHTML(onlineName+"上线了");
                }
                else if(obj.messageType==2){
                    $("#onLineUser").empty();
                    var onlineName = obj.onlineUsers;
                    var offlineName = obj.username;
                    var option = "<option>"+"--所有--"+"</option>";
                    for(var i=0;i<onlineName.length;i++){
                        if(!(onlineName[i]==document.getElementById('username').value)){
                            option+="<option>"+onlineName[i]+"</option>"
                        }
                    }
                    $("#onLineUser").append(option);
     
                    setMessageInnerHTML(offlineName+"下线了");
                }
                else if(obj.messageType==3){
                    var onlineName = obj.onlineUsers;
                    var option = null;
                    for(var i=0;i<onlineName.length;i++){
                        if(!(onlineName[i]==document.getElementById('username').value)){
                            option+="<option>"+onlineName[i]+"</option>"
                        }
                    }
                    $("#onLineUser").append(option);
                    console.log("获取了在线的名单"+onlineName.toString());
                }
                else{
                    setMessageInnerHTML(obj.fromusername+""+obj.tousername+"说:"+obj.textMessage);
                }
            };
     
            //连接关闭的回调事件
            webSocket.onclose = function()
            {
                console.log("连接已关闭...");
                setMessageInnerHTML("连接已经关闭....");
            };
        }
        else{
            // 浏览器不支持 WebSocket
            alert("您的浏览器不支持 WebSocket!");
        }
        //将消息显示在网页上
        function setMessageInnerHTML(innerHTML) {
            document.getElementById('message').innerHTML += innerHTML + '<br/>';
        }
     
        $("#sendMsgBtn").click(function(){
            
            var selectText = $("#onLineUser").find("option:selected").text();
            if(selectText=="--所有--"){
                selectText = "All";
            }
            else{
                setMessageInnerHTML(document.getElementById('username').value+""+selectText+"说:"+ $("#text").val());
            }
            var message = {
                "message":document.getElementById('text').value,
                "username":document.getElementById('username').value,
                "to":selectText
            };
            webSocket.send(JSON.stringify(message));
            $("#text").val("");
            
        });
    
        $("#closeBtn").click(function(){
             webSocket.close();
        });
        
    </script>
    </html>

    示例:

    参考:

    https://blog.csdn.net/qq_38455201/article/details/80374712

  • 相关阅读:
    AOP从静态代理到动态代理 Emit实现
    Emit基础入门 系列文章
    ContextAttribute与ContextBoundObject应用的探究
    吞云吐烦忧
    动态编译代码框架发布CZGL.Roslyn
    AutoMapper 入门
    Attribute在.net编程中的应用
    C#反射与特性 系列文章
    静态代理和动态代理方式分别实现AOP拦截功能
    内网安全攻防:渗透测试指南——第8章 权限维持分析及防御
  • 原文地址:https://www.cnblogs.com/moris5013/p/11492960.html
Copyright © 2020-2023  润新知