zoukankan      html  css  js  c++  java
  • springboot集成websocket实现给单人或多人发送数据

    服务器端:

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

      

    package cn.socket;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.*;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    
    @Component
    @ServerEndpoint("/pull/test/{id}")
    public class WebSocketServer {
    
        public WebSocketServer() {
            System.out.println("---------创建socket---------");
        }
    
        private static int onlineCount = 0;
        private static ConcurrentHashMap<String, WebSocketServer> webSocketSet = new ConcurrentHashMap<>();
        private static CopyOnWriteArraySet<WebSocketServer> webSockets =new CopyOnWriteArraySet<>();
    
        //与某个客户端的连接会话,需要通过它来给客户端发送数据
        private Session session;
    
        private static Logger log = LogManager.getLogger(WebSocketServer.class);
        private String id = "";
        /**
         * 连接建立成功调用的方法*/
        @OnOpen
        public void onOpen(@PathParam(value = "id") String id, Session session) {
            this.session = session;
            this.id = id;//接收到发送消息的人员编号
            webSocketSet.put(id, this);     //加入set中
            webSockets.add(this);
            addOnlineCount();           //在线数加1
            log.info("用户"+id+"加入!当前在线人数为" + getOnlineCount());
            try {
                sendMessage("连接成功");
            } catch (IOException e) {
                log.error("websocket IO异常");
            }
        }
    
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose() {
            webSocketSet.remove(this);  //从set中删除
            subOnlineCount();           //在线数减1
            log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用的方法
         *
         * @param message 客户端发送过来的消息*/
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("来自客户端的消息:" + message);
            //可以自己约定字符串内容,比如 内容|0 表示信息群发,内容|X 表示信息发给id为X的用户
            String sendMessage = message.split("[|]")[0];
            String sendUserId = message.split("[|]")[1];
            try {
                if(sendUserId.equals("0"))
                    sendtoAll(sendMessage);
                else
                    sendtoUser(sendMessage,sendUserId);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         *
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            log.error("发生错误");
            error.printStackTrace();
        }
    
    
        public void sendMessage(String message) throws IOException {
            this.session.getBasicRemote().sendText(message);
        }
    
    
        /**
         * 发送信息给指定ID用户,如果用户不在线则返回不在线信息给自己
         * @param message
         * @param sendUserId
         * @throws IOException
         */
        public void sendtoUser(String message,String sendUserId) throws IOException {
            if (webSocketSet.get(sendUserId) != null) {
                if(!id.equals(sendUserId))
                    webSocketSet.get(sendUserId).sendMessage( "用户" + id + "发来消息:" + " <br/> " + message);
                else
                    webSocketSet.get(sendUserId).sendMessage(message);
            } else {
                //如果用户不在线则返回不在线信息给自己
                sendtoUser("当前用户不在线",id);
            }
        }
    
        /**
         * 发送信息给所有人
         * @param message
         * @throws IOException
         */
        public void sendtoAll(String message) throws IOException {
            for (String key : webSocketSet.keySet()) {
                try {
                    webSocketSet.get(key).sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void sendtoAll2(String message) throws IOException {
            for (WebSocketServer webSocket : webSockets) {
                try {
                    webSocket.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        public static synchronized void addOnlineCount() {
            WebSocketServer.onlineCount++;
        }
    
        public static synchronized void subOnlineCount() {
            WebSocketServer.onlineCount--;
        }
    
    }
    

      

    @RestController("outController")
    @Api(tags = "外部接口管理")
    @CrossOrigin //跨域访问 swagger 要使用到
    public class OutController extends BaseController {
    
        @Autowired
        private WebSocketServer webSocketServer;
    
      
        @ApiOperation("推送数据")
        @GetMapping("/toHome")
        public void toHome() throws Exception {
            webSocketServer.sendtoAll2("1");
        }
    }
    

      前端代码:

    <!DOCTYPE html>
    <html style="height: 100%;">
    
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <title>创建缓冲区</title>
        
        
        
    </head>
    
    <body style="height: 100%;">
        
        <script type="text/javascript">
    	    const ws=new WebSocket('ws://localhost:33002/tianjin-cim/tuchu/apis/pull/test/1');
        ws.onmessage =function(e){
          console.log(e)
        };
    	
        </script>
    </body>
    
    </html>
    

      

  • 相关阅读:
    Java 装饰者模式
    struts2注解的作用
    XML DOM 笔记
    XMLHttpRequest的用法
    Eclipse中实现JS代码提示功能
    .after()和.before()的关系
    xml的的特殊字符转义&
    html和xml的区别
    dom4j的解析实例
    tld自定义标签系列--使用body-content的作用--比较有用
  • 原文地址:https://www.cnblogs.com/james-roger/p/14893552.html
Copyright © 2011-2022 走看看