浅析即时通讯开发WebSocket热门疑问

WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方便、应用广泛,已经渗透到前后端开发的各种场景中。

对http一问一答中二式流程(就是从所周之的“长轮询”技要啦)的不满,催生了支持双向通信的WebSocket诞生。WebSocket是个不太干净协议。

1问WebSocket:WebSocket协议只能浏览器发起么?

不是。目前此协议的受众的也不仅仅是web开发者。

WebSocket只是一种协议,它和http协议一样,使用类似okhttp的组件,可以在任何地方进行调用,甚至可以借助WebSocket实现RPC框架。

2问WebSocket:WebSocket和HTTP什么关系?

WebSocket和http一样,都是处于OSI模型中的最高层:应用层。

WebSocket借助http协议进行握手,握手成功后,就会变身为TCP通道,从此与http不再相见。

使用netstat或者ss,能够看到对应的连接,它与处于抽象层的socket,在外观上没有区别。

3问WebSocket:WebSocket和长轮询有什么区别?

长轮询,就是客户端发送一个请求,服务端将一直在这个连接上等待(当然有一个超长的超时时间),直到有数据才返回,它依然是一个一问一答的模式。比如著名的comted。

WebSocket在握手成功后,就是全双工的TCP通道,数据可以主动从服务端发送到客户端,处于连接两端的应用没有任何区别。

WebSocket创建的连接和Http的长连接是不一样的。由于Http长连接底层依然是Http协议,所以它还是一问一答,只是Hold住了一条命长点的连接而已。

长轮询和Http长连接是阻塞的I/O,但WebSocket可以是非阻塞的(具体是多路复用)。

4问WebSocket:如何创建一个WebSocket连接?

WebSocket的连接创建是借助Http协议进行的。这样设计主要是考虑兼容性,在浏览器中就可以很方便的发起请求,看起来比较具有迷惑性。

请求的地址,一般是:ws://\*\*\*,或者是使用了SSL/TLS加密的安全协议wss:,用来标识是WebSocket请求。

    1)首先,通过Http头里面的Upgrade域,请求进行协议转换。如果服务端支持的话,就可以切换到WebSocket协议。简单点讲:连接已经在那了,通过握手切换成ws协议,就是切换了连接的一个状态而已。
    2)Connection域可以认为是与Upgrade域配对的头信息。像nginx等代理服务器,是要先处理Connection,然后再发起协议转换的。
    3)Sec-WebSocket-Key 是随机的字符串,服务器端会用这些数据来构造出一个 SHA-1 的信息摘要。如此操作,可以尽量避免普通 HTTP 请求被误认为 WebSocket 协议。


其他的,像Sec-WebSocket*字样的头信息,表明了客户端支持的子协议以及其他信息。像loT中很流行的mqtt,就可以作为WebSocket的子协议。即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询

5问WebSocket:WebSocket如何处理数据?

WebSocket是通过事件通知的方式运行的。它包含四个事件和两个动作(发送和关闭)。

数据可直接通过Socket.send()方法进行传输。

通过chrome的Inspect->Network->WS,可以看到页面上的WebSocket连接。

、6问WebSocket:如何使用Nginx做WebSocket的负载均衡?

nginx官网已经给出了例子。主要是Upgrade和Connection头的设置。

Nginx的中的配置如下:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
 
location /chat/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

需要注意的是,nginx做负载均衡,不需要配置ip_hash等参数,nginx天然支持。由于ip_hash仅使用ip地址的前三个数字做hash,还有可能造成服务端的不均衡。

特别注意:

在IM聊天系统场景下,Nginx提供给WebSocket的这种所谓的“负载均衡”,只能解决传统分布系统中的SLB服务器要做的事。

通俗地说,Nginx只能帮助完成引导WebSocket客户连接到哪一个WebSocket服务端实例,在IM集群情况下,如果两个用户处于不同的WebSocket实例下时,它们之间的跨实例通信,Nginx是没有办法实现的,这一块的逻辑还是得IM开发者自已来实现。

总而言之,Nginx提供给WebSocket的所谓“负载均衡”,并不是IM开发者认为的那种全功能集群!

7问WebSocket:Java服务端怎么实现WebSocket?

可以使用javax.WebSocket下的包,简单的实现ws服务端。目前基本可以通过注解的方式去编写代码,比如ServerEndpoint。

推荐使用基于netty的netty-socketio进行服务端的编写。由于使用的是netty,所以能够在多个层面进行切入,获取一些统计数据,执行一些控制指令。socketio是一套解决方案,它有多个语言的客户端,并处理了市面上大多数的兼容问题。

友情忠告:socket.io几乎是市面上最好的开源WebSocket解决方案,但netty-socketio这个开源工程并非socket.io官方团队维护,而对于socket.io这个版本帝来说,其他的非官方版本能不能即时跟进,也是一个需要考虑的风险因素。

8问WebSocket:WebSocket能干些啥?

1)通知功能:

保持一个长连接,当服务端有新的消息,能够实时的推送到使用方。像知乎的点赞通知、评论等,都可以使用WebSocket通信。

某些使用H5的客户端,为了简化开发,也会使用WebSocket进行消息的通知,由于它是实时推送的,会有更好的用户体验。

2)数据收集:

一些次优级别的数据,比如行为日志、trace、异常执栈收集等,都可以开辟专门的WebSocket通道进行传输。这能够增加信息的集中度,并能及时的针对用户的行为进行合适的配置推送。由于大多数浏览器内核都支持,它将使客户端APM编程模型变得简单。

3)加密 && 认证:

虽然使用Fiddler、Charles等能够抓到很多WebSocket包。但如果同时开启SSL,传输加密后的二进制数据,会大幅增加破解的成本,会安全的多。

4)反向控制钩子:

这个...由于是双工长连接,服务端完全可以推送一些钩子命令,甚至直接是代码,在客户端进行执行。比如截个屏,录个音,种个小马。用户只要通过了授权申请,剩下的就随你发挥了。

支付宝偷偷调用你的相机给你拍照的梗,我是相信的。

猜你喜欢

转载自blog.csdn.net/wecloud1314/article/details/126345427