zoukankan      html  css  js  c++  java
  • websocket 点对点、广播推送

    废话就不多说了。

    1、springboot项目 引入websocket依赖

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

    2、springbooot在启动类中注入 ServerEndpointExporter

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

    3、Websocket组件类

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    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.CopyOnWriteArraySet;
    import java.util.concurrent.atomic.AtomicInteger;
    
    @Component
    @ServerEndpoint("/websocket/{sessionId}")
    public class WebSocket {
    
        private static final Logger logger = LoggerFactory  .getLogger(WebSocket.class);
    
        private static final AtomicInteger onlineCount = new AtomicInteger(0);
    
        private Session session;
    
        private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
    
        private String sessionId="";
    
        @OnOpen
        public void onOpen(Session session,@PathParam("sessionId") String sessionId) {
            this.session = session;
            this.sessionId=sessionId;
            webSockets.add(this);
            int count = onlineCount.incrementAndGet(); // 在线数加1
            logger.info("有连接加入,当前连接数为:{}", count);
            sendMessage("0");
    
        }
    
        /**
         * 关闭调用方法
         */
        @OnClose
        public void onClose() {
            webSockets.remove(this);
            int count = onlineCount.decrementAndGet();
            logger.info("有连接关闭,当前连接数为:{}", count);
        }
    
        @OnError
        public void onError(Session session, Throwable error) {
            logger.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());
            error.printStackTrace();
        }
    
        @OnMessage
        public void onMessage(String message, Session session) {
            logger.info("收到来自客户"+sessionId+"的信息:{}", message);
            sendMessage(message);
        }
    
        /**
         * 实现服务器主动推送
         */
        public void sendMessage(String message){
            try {//推送消息和当前socket通道的会话id (客户)
                this.session.getBasicRemote().sendText(message +"=="+ sessionId);
            } catch (IOException e) {
                logger.error("websocket异常: "+ e.toString());
            }
        }
    
    
        public static void sendInfo(String message,@PathParam("sessionId") String sessionId){
            logger.info("推送消息到窗口"+sessionId+",推送内容:"+message);
            for (WebSocket item : webSockets) {
                    //这里可以设定只推送给这个sid的,为null则全部推送
                    if(sessionId==null) {
                        item.sendMessage(message);
                    }else if(item.sessionId.equals(sessionId)){
                        item.sendMessage(message);
                    }
            }
    
        }
    
        /**
         * 消息广播到前台
         *
         * @param message
         */
        public void sendAllMessage(String message) {
            for (WebSocket webSocket : webSockets) {
                try {
                    webSocket.session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    logger.error("websocket异常: "+ e.toString());
                }
            }
        }
    
    }

    4、测试方法  点对点推送,偶数给客户a推送  奇数给客户b推送    推荐一个在线websocket测试工具:戳这里

        @Autowired
        private WebSocket webSocket;
    @RequestMapping(value
    = "/test", method = RequestMethod.POST, produces = "application/json;charset=utf-8") public String test(){ String sessionId = ""; for(int i=0;i<8;i++){ JSONObject js = new JSONObject(); js.put("isHasNewMessage", i); if (i %2 ==0){ sessionId = "a"; }else{ sessionId ="b"; } webSocket.sendInfo(js.toString(), sessionId); } return "成功"; }

    输入本机websocket地址 ws://ip:port/websocket/{}     说明 /websocket/{}  是websocket组件类的@ServerEndpoint("/websocket/{sessionId}") 中指明的路径后缀

    如图,现在建立a客户 的socket连接通道

     再建立b客户 的socket连接通道

     然后postman调用 测试方法  http://localhost:8080/test, 分别查看客户a和客户b的消息推送结果

    客户a:

     客户b:

     5、测试方法  广播推送,所有数据给客户a、客户b推送  

        @Autowired
        private WebSocket webSocket;
    @RequestMapping(value = "/test", method = RequestMethod.POST, produces = "application/json;charset=utf-8") public String test(){ String sessionId = ""; for(int i=0;i<8;i++){ JSONObject js = new JSONObject(); js.put("isHasNewMessage", i); if (i %2 ==0){ sessionId = "a"; }else{ sessionId ="b"; } webSocket.sendAllMessage(js.toString()); } return "成功"; }

    同样的,先建立两个客户a和客户b的连接,这里就不在重复操作截图了,直接调用测试方法,然后看客户a、客户b是否收到了消息

    客户a

    客户b

    其他相关的截图:浏览器同时开启两个socket连接 连客户a和客户b,然后调接口 

     客户端给服务器发送消息:

    1、首先建立客户a的连接,连接成功后,在下边的发送消息框中输入消息,然后点击发送

     2、可以看到如下效果 首先看控制台,分别是建立连接时候打印的有多少客户连接  然后 客户a发送给socket服务端的 歌词,最后看浏览器的页面

    ok,that's all

  • 相关阅读:
    go开发 modules 的使用和代理
    利用 nodejs 解析 m3u8 格式文件,并下 ts 合并为 mp4
    别再@官方啦,普天同庆加国旗
    vue基于 element ui 的按钮点击节流
    react-router 5.0 的鉴权
    slot 组件的内部传值 v-slot 的使用
    javascript 写一个ajax 自动拦截,并下载数据
    Linux 命令大全
    http 基础
    MongoDB Shell (mongo)
  • 原文地址:https://www.cnblogs.com/xuchao0506/p/14929646.html
Copyright © 2011-2022 走看看