实时传输的选择方案

发布时间:2026/7/4 2:01:36

实时传输的选择方案 针对聊天、订单状态推送这类实时数据更新等场景通常有多种解决方案一.普通短轮询就是固定时间轮询一次比如设置为10秒那就是会攒够10秒的所有信息再统一发送缺点1.无效请求占比高资源浪费严重假如一天就跟别人说了一句话那么只有那一句话的轮询是有效的其他时间的轮询就是无效轮询2.实时性差存在延长如果设置时间越短那么实时性当然就越好但这样无效请求就更多消耗资源就越严重那么出于优化将时间延长那么这样实时性就差了3.需要客户端不断发送请求导致客户端卡顿体验差若是移动端还会有电量消耗和流量消耗4.无法应对突发高并发针对突发流量短轮询会在这一段所有进行积攒然后就瞬间压垮服务端二.长轮询就是发送一次长轮询如果服务端没有数据就一直挂着保持连接直到有数据了/超时此时会立即返回信息超时就是空响应并断开连接客户端接收到响应后又马上再发送一次长轮询如此循环缺点1.仍然是HTTP请求每次发送轮询请求都会消耗网络开销三次握手/四次挥手2.连接挂在服务器仍然占用资源3.有空窗期在断开连接到再次发送连接这一段时间就是空窗期实时性不如无间隙的三.MQTT轻量级物联网通信协议主要采用发布者、订阅者、代理服务器三个角色主要用于物联网。四.WebRTC主要用于视频流、音频流的推送一般不用于传输文本数据五.WebSocket消息推送机制WebSocket是一个应用层协议与HTTP协议是并列同级的关系是基于传输层TCP实现的一个协议一旦连接建立完成客户端或服务端都可以主动的向对方发送数据。1.WebSocket的报文格式其中FIN就是表示是否要关闭WebSocket然后RSV有三位作为保留位就是现在不用留着以后用opcode是操作码描述了当前WebSocket数据帧是起到什么作用的比如说0x1这个操作码就表示是一个文本数据0x2表示是二进制数据所以WebSocket既可以传输二进制数据也可以传输文本数据MASK代表是否开启掩码操作掩码操作主要是为了避免“缓冲区溢出”的问题payload length也就是载荷长度因为有7个bit位所以是2^7-1127然后单位是字节127字节会不会太少了呢的确所以payload length有三种模式17bit当payload length126时采用模式1216bit当payload length是126时采用模式2364bit当payload length是127时采用模式3payload data那就是要传输的数据了2.WebSocket的握手过程一开始浏览器和服务器是采用HTTP协议进行发送浏览器给服务器发送的请求中会有一些特殊的header分别是Connectionupgrade升级和Upgradewebsocket第一个Connection表示我这次来的目的是想要从HTTP协议进行升级第二个Upgrade表示我要升级成哪种协议比如websocket同理服务器也会在响应报文中带上这两个特殊的header表示我也愿意跟你升级一下其中HTTP的状态码是101101就表示协议切换这下就建立了Websocket的连接就可以使用websocket进行数据传输3.WebSocket的使用先导入依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-websocket/artifactId /dependency继承TextWebSocketHandler类并重写方法package com.example.java_chatroom.api; import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; Component public class TestWebSocketAPI extends TextWebSocketHandler { Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 这个方法会在 websocket 连接建立成功后, 被自动调用. System.out.println(TestAPI 连接成功!); } Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 这个方法是在 websocket 收到消息的时候, 被自动调用的. System.out.println(TestAPI 收到消息! message.toString()); // session 是个会话, 里面就记录了通信双方是谁. (session 中就持有了 websocket 的通信连接) session.sendMessage(message); } Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 这个方法是在连接出现异常的时候, 被自动调用的. System.out.println(TestAPI 连接异常!); } Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { // 这个方法是在连接正常关闭后, 被自动调用的 System.out.println(TestAPI 连接关闭!); } }然后再创建一个WebSocketAPI类继承TextWebSocketHandler重写这几个方法具体代码就根据实际业务来编写再对websocket进行配置package com.example.java_chatroom.config; import com.example.java_chatroom.api.TestWebSocketAPI; import com.example.java_chatroom.api.WebSocketAPI; import org.springframework.beans.factory.annotation.Autowired; 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; import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; Configuration EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { Autowired private TestWebSocketAPI testWebSocketAPI; Autowired private WebSocketAPI webSocketAPI; Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // 通过这个方法, 把刚才创建好的 Handler 类给注册到具体的 路径上. // 此时当浏览器, websocket 的请求路径是 /test 的时候, 就会调用到 TestWebSocketAPI 这个类里的方法. // registry.addHandler(testWebSocketAPI, /test); registry.addHandler(webSocketAPI, /WebSocketMessage) // 通过注册这个特定的 HttpSession 拦截器, 就可以把用户给 HttpSession 中添加的 Attribute 键值对 // 往我们的 WebSocketSession 里也添加一份. .addInterceptors(new HttpSessionHandshakeInterceptor()); } }4.Websocket连接断开的判断和重连机制Websocket内置了心跳包机制所以在断开后就能感知到是否连接断开并且提供了onclose和onerror回调就能在断开后通过回调通知到业务代码关于重连的机制有六种1立即重连优点是能够短时间内快速恢复连接缺点是当无法重连时会对服务器造成额外压力导致资源的无效循环利用2指数退避策略每次重连失败后会增加延迟采用的是指数退避策略也就是说每一次失败等待时间会越来越久可以减少对服务器的压力并且最后能够重新建立上连接3设置重试限制设置最大重试次数防止客户端不断重试连接到不可用的服务器从而避免了不必要的资源使用4超时设置为每次重连设置合理的超时值避免无限期等待服务器响应5用户反馈在用户界面有明确清晰的连接状态反馈6错误处理在重连失败后提供明确的错误信息六.WebTransport目的是解决传统协议如WebSocket的一些局限性但使用的广泛程度不如websocket而WebTransport是基于UDP协议实现的可以通过流API可靠地发送数据以及数据报API不可靠地发送数据相比于WebSocket的优势高级功能WebSocket很难通过单个连接发送不同类型的数据因为对数据进行分包的时候无法区分数据中不同类型的编码因此就需要建立多个连接然后不同连接发送不同格式的数据。而WebTransport支持多个流也就是多路复用即可以通过一个连接发送不同类型的数据从而减少建立和维护多个连接的开销。改进性能WebTransport是一种基于UDP的传输协议比基于TCP的协议如Websocket性能更高因为缺乏纠错和重传功能延迟会更低可靠性虽然没有纠错和重传功能但并非不如WebSocket可靠在设计上就比WebSocket更可靠为可靠的单向或双向数据传输提供了流API由底层QUIC协议实现通过切换为流API这个模式就包含重传、确认、无乱序等可靠机制安全性默认提供端到端加密确保在传输过程中不会被截获或修改其中一个安全功能是使用“Origin”标头 为服务器能够验证请求是否来自可靠信源有助于防止跨站请求伪造

相关新闻