SpringBoot+websocket实现实时的点对点或群发通信(内附详细代码实现)

websocket原理

WebSocket用于在Web浏览器和服务器之间进行任意的双向数据传输的一种技术。WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。

1. 什么是keep-alive

keep-alive只是客户端的一种建议

我们打开百度首页,进一步查看header。 
这里写图片描述

如图,我们看到请求header中有一行:

Connection:keep-alive
  •  

1.keep-alive是通知服务器,在这个HTTP Request/Responset结束后,不要立即断开TCP连接(注意是TCP连接,和HTTP没有关系),后面的HTTP Request仍然可以通过这个TCP连接继续传送。

但是!这只是个建议,服务器可能不支持,也可能忽略掉这个建议。也可能因为时间太久而直接断开TCP连接

通俗点解释就是:keep-alive只是通知服务器,您先别挂,一会儿可能还有活儿,至于它挂不挂还是看它心情。 
所以,keep-alive只是客户端建议的一种复用TCP连接的方式,至于服务器支持不支持,就由不得客户端了。

keep-alive只是http协议中的一部分 
keep-alive是http协议中的一部分,也即客户端可以主动的发起request到服务器,服务器只能被动的response给客户端。 
我要想实现服务器主动的push消息给客户端,keep-alive是无能无力的。

2. 服务器的消息如何发给客户端

long long ago~ 服务器端要想主动的push消息给客户端(比如网页聊天室消息的即时收发),这是不可能滴。 
但是,我可以使用ajax轮询、long poll 技术造一个服务端给客户端主动push消息的假象。

①:什么是ajax轮询?

ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

场景再现:

客户端:啦啦啦,有没有新信息(Request) 服务端:没有(Response) 客户端:啦啦啦,有没有新信息(Request) 
服务端:没有。。(Response) 客户端:啦啦啦,有没有新信息(Request) 服务端:你好烦啊,没有啊。。(Response) 
客户端:啦啦啦,有没有新消息(Request) 服务端:好啦好啦,有啦给你。(Response) 
客户端:啦啦啦,有没有新消息(Request) 服务端:。。。。。没。。。。没。。。没有(Response) —- loop

但是这样,有没有发现,大大增加了服务端的负载,并且速度还慢。

②:什么是long poll?

long poll和ajax差不多,原理都是采用轮询的方式。只不过long poll是采取的阻塞的方式去轮询。 
也即客户端发起一个请求连接,这个连接会阻塞住,直到服务端有了消息,才会response给客户端。

场景再现:

客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) 服务端:额。。 等待到有消息的时候。。来 
给你(Response) 客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop

long pull 虽然降低了服务器的负载,但是需要服务器有很高的并发能力才可以。 
而目前处理高并发的模型基本都是异步非阻塞的模型(比如nginx)。

③:总结 
ajax轮询、long poll技术虽然都能实现服务端消息的实时通知,但是各有缺点,都不是根本的解决办法。 
计算机界急需一种新的技术去处理这些需求~

3. websocket来啦

既然ajax轮询、long poll都不怎么样。我们发明一种新的协议吧!

Websocket协议解决了服务器与客户端全双工通信的问题。

注:什么是单工、半双工、全工通信? 信息只能单向传送为单工; 信息能双向传送但不能同时双向传送称为半双工; 
信息能够同时双向传送则称为全双工。

websocket协议解析 
wensocket协议包含两部分:一部分是“握手”,一部分是“数据传输”。 
为了便于演示,我们采用swoole建立一个websocket服务器来演示。

第一步、握手

①客户端向服务端发起连接请求 
这里写图片描述

如图,我们在请求服务器的时候,发送了这样的request header。

下面我们就一些比较重要的字段信息进行说明:

Connection:Upgrade #通知服务器协议升级 Upgrade:websocket #协议升级为websocket协议 
Host:0.0.0.0:9501 #升级协议的服务主机:端口地址 
Sec-WebSocket-Key:K8o1cNIxO2pR6inTIDBSgg== #传输给服务器的key 
Sec-WebSocket-Version:13 #websocket协议版本13

Sec-WebSocket-Key有什么用呢? 
客户端将这个key发送给服务器,服务器将这个key进行处理,将处理后的key返回给客户端,客户端根据这个key是否正确来判断是否建立连接。

②:服务端返回握手应答 
这里写图片描述 
如图,我们看到websocket协议状态码是101.

101表示协议切换成功。
  • 1

我们查看websocket的response header。如图: 
这里写图片描述
下面解释下reponse header字段的含义

Connection:Upgrade #协议升级成功 
Sec-WebSocket-Accept:GnoYH/ip/ZMh+a5rX5P/YR6e68g= #服务端处理之后的key 
Sec-WebSocket-Version:13#websocket 协议版本号 
Upgrade:websocket#协议升级为websocket

至此,websocket握手成功!下面就尽情的传输数据吧!

第二步、数据传输

  • 9
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值