SpringBoot集成实时通讯WebSocket和其它代替方案

WebSocket 双向实时通讯

一、添加WebSocketConfig配置类

/**
* 开启WebSocketConfig
*/
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

二、创建WebSocket服务处理类

/**
*  服务处理类
*/
@ServerEndpoint("/websocket/{sid}/{name}")
@Component
public class WebSocketServer {
    static Log log = LogFactory.get(WebSocketServer.class);
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    //concurrent包的线程安全Set,用来存放每个客户端对应的会话
    private static CopyOnWriteArraySet<Session> sessions = new CopyOnWriteArraySet<>();

    // 注入bean
    private static RedisCache redisCache;
    @Authowired
    public void setRedisCache(RedisCache redisCache){
        this.redisCache = redisCache;
    }

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid, @PathParam("name") String name) {
        sessions.add(session);
        addOnlineCount();           //在线数加1
        log.info("有新窗口开始监听:" + sid + "|" + name + ",当前在线人数为" + getOnlineCount());
        try {
            session.getBasicRemote().sendText("连接成功");
        } catch (IOException e) {
            log.error("websocket IO异常");
            e.printStackTrace();
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        sessions.remove(session);
        subOnlineCount();           //在线数减1
        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        String name = session.getPathParameters().get("name");
        log.info("收到来自窗口[" + session.getId() + "|" + name + "]的信息:" + message);
        // 可以收到客户端消息,可以根据消息指令处理一些业务(推送消息给前端/关闭推送/其它业务处理)
    }
    /**
     * 实现服务器主动推送
     */
    public synchronized void sendMessage(String message, String sessionId, String name) {
        log.info("推送消息到任务窗口[" + sessionId  + "|" + name + "],推送内容:" + message);
        for (Session session : sessions) {
            try {
                if(session.getId().equals(sessionId)){
                    session.getBasicRemote().sendText(message);
                }
            } catch (Exception e) {
                continue;
            }
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}

三、vue前端

在data中创建websock对象

/**
* 创建websocket
*/
initWebSocket(){
    console.log("创建WebSocket")
    this.websock = new WebSocket("ws://127.0.0.1:9998/websocket/ydsj")
    this.websock.onmessage = this.websocketonmessage
    this.websock.onerror = this.websocketonerror
    this.websock.onopen = this.websocketonopen
    this.websock.onclose = this.websocketclose

},
// 连接建立之后执行send方法发送数据
websocketonopen () {
   let data = {
     code: 0,
     msg: '这是client:初次连接'
   }
   this.websocketsend(data)
},
websocketonerror () {
  console.log( 'WebSocket连接失败')
},
// 数据接收
websocketonmessage (e) {
   console.log('数据接收' + e.data)
},
// 数据发送
websocketsend (Data) {
   this.websock.send(Data)
},
// 关闭
websocketclose (e) {
   console.log('已关闭连接', e)
}

WebSocket 其它替代方案

SSE 服务器发送事件

服务器发送事件Server-Sent-Events(SSE)是一种服务器推送技术,允许服务器通过单个 HTTP 连接向客户端推送数据。

SSE 与 WebSocket 作用相似,都是建立浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息。

总体来说,WebSocket 更强大和灵活。因为它是全双工通道,可以双向通信;SSE 是单向通道,只能服务器向浏览器发送,因为流信息本质上就是下载。如果浏览器向服务器发送信息,就变成了另一次 HTTP 请求。

Server-Sent-Events(SSE)是一种HTML5 API,用于在服务器和客户端之间实时推送数据流。 SSE可以用于实现实时通知、实时聊天、实时数据更新和实时监控等功能。

  • SSE 默认支持断线重连,WebSocket 需要自己实现。
  • SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。
  • SSE 支持自定义发送的消息类型。
  • SSE 基于 HTTP 协议,目前除了 IE/Edge,其他浏览器都支持。

长轮询

长轮询是一种客户端向服务器发送 HTTP/HTTPS 请求的方法,但客户端不会立即收到服务器的响应,而是需要保持 HTTP 连接。保持 HTTP 连接可使服务器在数据可用或达到超时阈值时稍后回复。收到响应后,客户端将立即发送后续请求。

长轮询无需 WebSockets 提供的双向通信通道就能实现实时通信。其核心区别在于,客户端将发送多个请求来重新建立与服务器的连接,而不是像 WebSockets 那样维护一个持久连接。

MQTT

MQTT 是一种轻量级的发布-订阅式机器对机器网络协议,专为网络带宽有限的远程设备而设计。由于资源限制,智能传感器、可穿戴设备和其他物联网设备通常需要使用这种协议。虽然 WebSockets 可用于各种应用,但 MQTT 是明确为机器对机器通信而设计的,因此在这些使用案例中被视为一种替代方案。MQTT 具有开销低、消息传递效率高和支持离线操作等特点。

WebRTC

WebRTC 是一个免费的开源项目,可为 Web 浏览器和移动设备提供实时通信。它由 C++ 和 JavaScript 编写,可为网络浏览器和移动设备提供实时通信。WebRTC 可直接从点对点流式传输音频和视频,无需服务器端连接或额外插件。对于实时流媒体、视频会议或群组通话等用例,这些功能可通过 HTML5 和 JavaScript 使用 WebRTC API 快速实现。总之,在这些使用案例中,WebRTC 的点对点特性有助于减少服务器负载,并提供比 WebSockets 更高效、更高质量的通信体验。

WebTransport

WebTransport 是一种新的 Web 通信协议,可在客户端和服务器之间提供低延迟、高吞吐量的连接。它的创建是为了解决传统协议(如 WebSockets)的一些局限性,并提供一种能更好地满足当今网络应用需求的现代替代方案。

WebTransport 是一个协议框架,该协议使客户端与远程服务器在安全模型下通信,并且采用安全多路复用传输技术。最新版的WebTransport草案中,该协议是基于HTTP3的,即WebTransport可天然复用QUIC和HTTP3的特性。

posted @ 2022-09-22 11:20  盗梦笔记  阅读(476)  评论(0编辑  收藏  举报