如何实现服务端向客户端推送数据

简介: 常见的http协议只能从客户端主动向服务端请求数据,而服务端无法向客户端发送数据.本文通过介绍几种方式来实现上述功能.

以微信朋友圈为例:
朋友圈提供动态点赞与评论功能,我们需要一种机制或方法保证用户在使用朋友圈过程中能相对实时地收到其他用户的点赞和评论消息。简单来说,就是实现双向通信。常用的Http协议通信只能由客户端发起,服务端接收到请求并做出应答,显得十分被动,这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。

经过调研,找到以下几种实现双向通信的方式:

1.轮询(polling):让客户端隔个几秒就发送一次请求,询问服务器是否有新信息。

用大白话举例就是:

while True: 客户端:妹子,请你吃饭有空吗?(Request)

服务端:没有!(Response)

客户端:妹子,请你吃饭有空吗?(Request)

服务端:没有。。(Response)

客户端:妹子,请你吃饭有空吗?(Request)

服务端:你好烦啊,没有啊。。(Response)

客户端:妹子,请你吃饭有空吗?(Request)

服务端:好啦好啦,有啦。(Response)

客户端:妹子,请你吃饭有空吗?(Request)

服务端:。。。。。没。。。。没。。。没有(Response)

  • 优点:实现简单,无需做过多的更改
  • 缺点:轮询的间隔过长,会导致用户不能及时接收到更新的数据;轮询的间隔过短,会导致查询请求过多,增加服务器端的负担

2.长轮询(long-polling):长轮询其实原理跟轮询差不多,都是采用轮询的方式,不过采取的是阻塞模型,也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

还是用大白话举例:

while True:

客户端:妹子,请你吃饭有空吗?没有的话就等有了再返回给我吧!(Request)

服务端:(额。。现在好忙,先不回复他,电话先不挂。)

服务端:现在有空了。(Response)

客户端:妹子,请你吃饭有空吗?没有的话就等有了再返回给我吧!(Request)

服务端:(额。。现在好忙,先不回复他,电话先不挂。)

服务端:现在有空了。(Response)

  • 优点:比 polling 做了优化,有较好的时效性
  • 缺点:保持连接会消耗资源;服务器没有返回有效数据,程序超时

3.iframe流(streaming):iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长连接,服务器向iframe传输数据,来实时更新页面。

while True:

客户端:妹子,请你吃饭有空吗?(Request)

服务端:您好,您所拨打的用户正在通话中,请稍后再拨。(503 Server Unavailable)

客户端:妹子,请你吃饭有空吗?(Request)

服务端:您好,您所拨打的用户正在通话中,请稍后再拨。(503 Server Unavailable) 服务端忙的要死:(我要更多的资源,资源。。。)

  • 优点:消息能够实时到达;浏览器兼容好
  • 缺点:服务器维护一个长连接会增加开销;IE、chrome、Firefox会显示加载没有完成,图标会不停旋转。

经过个人的评估,得出了最优解

WebSocket,它是基于TCP/IP协议,独立于HTTP协议的通信协议,而且能实现客户端与服务端双向实时响应(客户端 ⇄ 服务端)。
客户端:我要建立WebSocket协议,需要的服务:chat,WebSocket协议版本:17(HTTP Request)

服务端:ok,确认,已升级为WebSocket协议(HTTP Protocols Switched)

客户端:你有事的时候记得要找我噢!

服务端:ok,有事的时候会找你的。 服务端:我想吃炸鸡了。 服务端:我想喝奶茶了。 服务端:我不开心了。

服务端:balabalabalabala。。。

选择原因:

  • 支持双向通信,实时性更强
  • 可以发送文本,也可以发送二进制数据
  • 减少通信量:只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了。
  • 方便与springboot集成,降低开发成本

相对于传统的HTTP每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket是类似Socket的TCP长连接的通讯模式,一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端断掉连接前,不需要客户端和服务端重新发起连接请求。 在海量并发和客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

具体的技术实现如下(模拟朋友圈):
当用户进入朋友圈,前端监听到对应事件,带上当前用户的token开始与服务端建立websocket连接,服务端接收到请求,解析请求的token,获取到该用户的openId,把它作为key,缓存当前连接的session()。当其他用户对该用户的动态点赞或评论,服务端接收到请求并执行完相关的逻辑后会查找session缓存中是否存在该动态发布者的session,若存在(该用户在线),则找到该session,并发送消息通知,动态发布者的客户端收到通知后会在浏览动态页右上角显示小红点,提醒用户有未读消息。

相关文章
|
JavaScript
HTTP/2 协议-服务端主动推送消息
HTTP/2 协议-服务端主动推送消息
461 0
|
XML 前端开发 网络协议
服务器向客户端推送消息的2种技术分析
服务器向客户端推送消息的2种技术分析
|
XML 消息中间件 传感器
HTTP 与 MQTT:为您的 IoT 项目选择最佳协议
HTTP 与 MQTT:为您的 IoT 项目选择最佳协议
1409 2
|
Web App开发 移动开发 前端开发
还在用轮询吗,SSE服务端推送实现页面实时更新
最近开发一个页面碰到一个需求,需要对部分数据需要实时更新状态
472 0
|
9月前
|
网络协议 Python
python中socket客户端发送和接收数据
【4月更文挑战第7天】本教程聚焦TCP客户端数据发送与接收。使用Python的`socket`模块,通过`send()`发送字节串至服务器,如`client_socket.send(message_bytes)`;用`recv()`接收数据,如`received_data = client_socket.recv(buffer_size)`。异常处理确保网络错误时程序健壮性,例如`try-except`捕获`socket.error`。理解和掌握这些基础操作对于构建稳定的TCP客户端至关重要。
1680 1
|
负载均衡 NoSQL 算法
聊聊 分布式 WebSocket 集群解决方案(一)
聊聊 分布式 WebSocket 集群解决方案
2776 0
聊聊 分布式 WebSocket 集群解决方案(一)
|
9月前
|
存储 缓存 Java
spring的三级缓存,以及循环依赖的形成和解决(详细)
spring的三级缓存,以及循环依赖的形成和解决(详细)
1022 0
|
6月前
|
Java
一文讲明 网络调试助手的基本使用 NetAssist
文章介绍了网络调试助手NetAssist的基本使用方法,包括创建客户端和服务端,模拟网络连接和数据发送,并通过Java代码示例展示了客户端与服务端之间的通信过程。
一文讲明 网络调试助手的基本使用 NetAssist
|
9月前
|
监控 安全 持续交付
【专栏】Webhook是服务器主动发送事件通知的机制,打破传统客户端轮询模式,实现数据实时高效传递。
【4月更文挑战第29天】Webhook是服务器主动发送事件通知的机制,打破传统客户端轮询模式,实现数据实时高效传递。常用于持续集成部署、第三方服务集成、实时数据同步和监控告警。具有实时性、高效性和灵活性优势,但也面临安全风险和调试挑战。理解并善用Webhook能提升系统性能,广泛应用于现代软件开发和集成。
493 0

热门文章

最新文章