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

 

posted @ 2021-06-25 09:57  ジ绯色月下ぎ  阅读(980)  评论(1编辑  收藏  举报