• Springboot集成WebSocket通信全部代码,即扣即用。


    websocket通信主要来自两个类以及一个测试的html页面。
    MyHandler 和 WebSocketH5Config,下面全部代码
    MyHandler类全部代码:
    package com.union.common.config;
     
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    import com.alibaba.fastjson.JSONObject;
    import org.springframework.stereotype.Service;
    import org.springframework.web.socket.CloseStatus;
    import org.springframework.web.socket.TextMessage;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.WebSocketMessage;
    import org.springframework.web.socket.WebSocketSession;
     
     
    @Service
    public class MyHandler implements WebSocketHandler {
    	
        //在线用户列表
        private static final Map<String, WebSocketSession> webSocketUsers;
    
        static {
            webSocketUsers = new HashMap<>();
        }
        //新增socket
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        	 String ID = session.getUri().toString().split("uid=")[1];
             if (ID != null) {
                 webSocketUsers.put(ID, session);
                 session.sendMessage(new TextMessage("成功建立socket连接"));
    
             }
        }
     
        //接收socket信息
        @Override
    	public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        	try{
    	    	JSONObject jsonobject = JSONObject.parseObject((String) webSocketMessage.getPayload());
                String message = (String) jsonobject.get("message");
                if (message == null) {
                    message = "服务器收到了,hello!";
                }
                sendMessageToUser(jsonobject.get("id")+"",message);
        	 }catch(Exception e){
          	   e.printStackTrace();
             }
    	}
     
        /**
         * 发送信息给指定用户
         * @param clientId
         * @param message
         * @return
         */
        public boolean sendMessageToUser(String clientId, String message) {
            if(webSocketUsers.get(clientId) == null){
                return false;
            }
            WebSocketSession session = webSocketUsers.get(clientId);
            if(!session.isOpen()) {
                return false;
            }
            try {
                session.sendMessage(new TextMessage(message));
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
     
        /**
         * 广播信息
         * @param message
         * @return
         */
        public boolean sendMessageToAllUsers(String message) {
            boolean allSendSuccess = true;
            Set<String> clientIds = webSocketUsers.keySet();
            WebSocketSession session = null;
            for (String clientId : clientIds) {
                try {
                    session = webSocketUsers.get(clientId);
                    if (session.isOpen()) {
                        session.sendMessage(new TextMessage(message));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    allSendSuccess = false;
                }
            }
     
            return  allSendSuccess;
        }
    
        /**
         * 关闭连接
         * @param clientId
         * @return
         */
        public void afterConnectionClosed(String clientId) {
            try {
                if(webSocketUsers.get(clientId) != null){
                    WebSocketSession session = webSocketUsers.get(clientId);
                    afterConnectionClosed(session,CloseStatus.NORMAL);
                }
                webSocketUsers.remove(clientId);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
     
     
        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
            String uid = session.getUri().toString().split("uid=")[1];
            webSocketUsers.remove(uid);
            if (session.isOpen()) {
                session.close();
            }
        }
     
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            String uid = session.getUri().toString().split("uid=")[1];
            webSocketUsers.remove(uid);
            session.close(status);
        }
     
        @Override
        public boolean supportsPartialMessages() {
            return false;
        }
    }
    

      

    WebSocketH5Config 类全部代码:

    package com.union.common.config;
    
    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;
    
    
    //实现接口来配置Websocket请求的路径和拦截器。
    @Configuration
    @EnableWebSocket
    public class WebSocketH5Config implements WebSocketConfigurer {
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            //handler是webSocket的核心,配置入口
            registry.addHandler(new MyHandler(), "/myHandler/{uid}").setAllowedOrigins("*");
        }
    }
    

      

    测试用的html页面:

    <!DOCTYPE html>
    <html>
    <head>
        <title>socket.html</title>
        <meta name="content-type" content="text/html" charset="UTF-8">
    </head>
    <body>
    
    Welcome<br/>
    登录的uid:<input id="uid" type="text"/><br/>
    <button onclick="connectWebSocket()">connectWebSocket</button><br/>
    发送出去的信息:<input id="text" type="text"/><br/>
    发送送给谁的uid:<input id="sendToUid" type="text"/><br/>
    <button onclick="send()">Send</button><br/>
    收到的信息:<input id="getMessage" type="text"/><br/>
    <button onclick="closeWebSocket()">Close</button>
    <div id="message">
    </div>
    </body>
    <script type="text/javascript">
        var websocket = null;
        //强制关闭浏览器  调用websocket.close(),进行正常关闭
        window.onunload = function () {
            //关闭连接
            closeWebSocket();
        }
    
        //建立WebSocket连接
        function connectWebSocket() {
            var userID = document.getElementById("uid");
            console.log(userID);
            console.log("开始...");
    
            //建立webSocket连接
            websocket = new WebSocket("ws://localhost:8080/myHandler/uid=" + userID.value);
    
            //打开webSokcet连接时,回调该函数
            websocket.onopen = function () {
                console.log("onpen");
            }
    
            //关闭webSocket连接时,回调该函数
            websocket.onclose = function () {
                //关闭连接
                console.log("onclose");
            }
    
            //接收信息
            websocket.onmessage = function (msg) {
                var getMessage = document.getElementById("getMessage");
                getMessage.value = msg.data;
                console.log(msg.data);
            }
        }
    
        //发送消息
        function send() {
            var sendToUid = document.getElementById("sendToUid");
            var messageText = document.getElementById("text");
            var postValue = {};
            postValue.id = sendToUid.value;
            postValue.message = messageText.value;
            websocket.send(JSON.stringify(postValue));
        }
    
        //关闭连接
        function closeWebSocket() {
            if (websocket != null) {
                websocket.close();
            }
        }
    
    </script>
    </html>
    

      

    因为websocket使用的是ws协议。所以我在nginx上做了一个请求转发,这样服务器就可以使用:

    在nginx.conf文件里面的http部分加入如下代码。

    map $http_upgrade $connection_upgrade {
            default upgrade;
            ''      close;
        }
    

      

    在server{}部分加了如下代码。放在最前面,就可以在ws部分使用域名访问了:

    ws和wss就像http和https一样的

    wss://api.****.com/union-front/myHandler/uid=
      location ~* /union-front/myHandler {
            proxy_pass http://127.0.0.1:8080;
            proxy_redirect    off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Origin "";
            }
    

      

     当使用websocket的时候,再使用定时任务,则会报错,在Application启动类上加上如下代码即可解决这个问题

    @Bean
        public TaskScheduler taskScheduler() {
            //使用 websockt注解的时候,使用@EnableScheduling注解启动的时候一直报错,增加这个bean 则报错解决。
            ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
            taskScheduler.setPoolSize(10);
            taskScheduler.initialize();
            return taskScheduler;
        }
    

      

  • 相关阅读:
    Java System.getProperty vs System.getenv
    Bring JavaScript to your Java enterprise with Vert.x
    es4x 引用外部jar 包以及集成typescrip
    cube.js 最近的一些更新
    es4x 调用其他三方jar 包
    graalvm native image 试用
    es4x 使用nodejs 开发vertx 应用框架试用
    clojure 环境搭建
    restql 学习三 查询语言简单说明
    restql 学习二 几种查询模式
  • 原文地址:https://www.cnblogs.com/hahahehexixihoho/p/10795837.html
Copyright © 2020-2023  润新知