WebSocket是什么原理?为什么可以实现持久连接?


WebSocket是什么原理?为什么可以实现持久连接?

首先需要明白:基于TCP的应用层协议,只要设计者愿意,都是可以实现持久连接的。你问的方式,大概是在和HTTP做比较。HTTPty等大量优秀的项目都在等你。还是要感谢大家对我写的东西有那么一点感兴趣,能对大家有所帮助就更好了。

解释WebSocket为什么可以实现持久连接,还是先介绍一些什么是WebSocket,以及它产生的原因是什么。是什么WebSocket?WebSocket是一个协议。协议就是王八的屁股——规定,你可以不遵守,但是别人都遵守你不遵守,你就跟别人玩不到一块去。WebSocket协议在年诞生,年成为了国际标准,现在绝大部分浏览器都已经支持了。产生的原因其实原因是为了弥补HTTP协议的不足,因为HTTP协议只能由客户端发起请求,并且一个Request要对应一个Response(长链接也是如此)。举个例子:我之前做过一个小项目,只有一个页面,展示的是各个分公司当天的业绩,就是挣了多少钱。后台服务是Java,数据库是Mysql,有一张汇总表,内容大概是北京-100万,上海-80万这样的。流程很简单,HTML页面发起请求到Java,Java访问数据库查询数据,再返回给HTML展示。但是Mysql中的汇总表的数据,是不定期更新的,可能10分钟,可能20分钟。最简单的做法:HTML中用JS设置一个定时轮询(Polling),每隔几秒去发起一次请求,获取最新的数据,如果数据没有变化,页面也保持变化;缺点很明显,前端发起的很多请求都是无效的(因为数据没有变化)。WebSocket的通信原理而WebSocket,是要在客户端和服务器之间,建立一个通道,建立一个【真的长链接】。WebSocket是要借助于HTTP,完成一部分工作。我在找到一个WebSocket在线测试的网站,打开之后查看请求和响应(具体网站连接也看下面图片中的信息)。可以看出来协议里面多了两行:Upgrade:websocketConnection:Upgrade这个就是关键内容了,通过请求告诉服务器:看清楚咯,请求要用WebSocket协议。服务器会回答:好的,那我就切换到WebSocket协议啦。到了这时候,HTTP完成它所有工作,客户端和服务器已经建立好了一个通道,下面就按照WebSocket协议进行了,服务端也就可以主动推送信息给客户端(双向),并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接,故此WebSocket也就实现了持久连接。希望我的回答,能够帮助到你!我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。

很高兴能够看到和回答这个问题!WebSocket是什么原理?WebSocket通过常见的HTTP协议进行数据连接,一般走的是TCP通道,WebSocket是一个允许单TCP连接之间全双工通信的协议。在WebSocketAPI中,浏览器和服务器只需要一次远程连接,而不是三次远程连接连接到TCP服务器,这样就可以直接持久连接和双向数据传输。WebSocket的特点WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。缺陷:HTTP的通信只能由客户端发起建立在TCP协议之上WebSocket特点性能开销小通信高效客户端可以与任意服务器通信协议标识符wswss持久化网络通信协议通常情况下,浏览器向服务器发送一个请求,工作完成后再向客户端返回一个消息。如果需要主动向浏览器提供数据,可以使用Web套接字。在向对方发送消息之前,先在服务器上维护一个Web套接字连接,然后在前端维护一个,再维护Web套接字。Websocket使用ws或wss协议,对应http或https。在WebSocket远程连接成功后,这是一个全双工的TCP通道,在这个通道上可以无差别的从工作日结束后向客户端发送数据。WebSocket创建的绑定与长HTTP绑定不同。由于长期的地下室还是HTP协议,他还是提出了一个问题,但只是长期保持联系。为什么可以实现持久连接?WebSocket协议是由HTML5标准定义的,它最初是为浏览器设计的,避免了相似性的限制。因为浏览器可以和任何工作端进行通信,现代的浏览器大多支持WebSocket。虽然WebSocket最初定义为HTML5,但它同样适用于移动终端。虽然可以通过Socket直接与终端连接,但使用WebSocket可以有效防止一些防火墙的窃听。WebSocket建立了一个连接,我们称之为持久连接,每个连接都是服务器的一个资源。但是,如果服务器长时间没有消息通信,就会倾向于关闭连接。其实,WebSocket的任务就是及时向桌面端发送空白消息,保证连接不会自动断开。很多网站采用技术实现推送技术。当浏览器向服务器发送HTTTP请求时,在一定的时间间隔内(如1秒)进行轮询,然后服务器将最新的数据返回给客户端的浏览器。这种传统的模式有明显的缺点,那就是浏览器需要不断地访问服务器,但HTTTP请求中会包含一个较长的头,在这个头中,真正有效的数据只能占据一小部分,这似乎造成了很多资源(如带宽)的浪费。第一次连接到Web套接字时,使用普通的HTTP与服务器通信,与Web套接字交换消息。一旦建立了Web套接字连接,所有的消息都可以通过这个通道发送。同时,客户端和服务器会继续使用乒乓球保持心跳,防止非正常断线。将网站的刷新逻辑移植到支持的浏览器上很容易,只需要找一些webssocket接口使用双webssocket属性即可。因为协议是完全双向的,服务器可以随时主动向客户端发送数据。与HTTP请求相比,接收客户请求的响应所需的延迟要少得多。即使与彗星等长时间的轮询相比,也可以在短时间内更频繁地传输数据。答案写到这里,我想您应该明白了WebSocket的原理,也知道了WebSocket可以实现持久连接的原因。WebSocket是基于web的一项新技术,它克服了以往HTTP协议下访问速度较慢容易断开连接,网站假死的现象。未来WebSocket技术将全面普及,提高我们的上网体验!以上便是我的一些见解和回答,可能不能如您所愿,但我真心希望能够对您有所帮助!不清楚的地方您还可以关注我的头条号“每日精彩科技”我将竭尽所知帮助您!码字不易,感觉写的还行的话,还请点个赞哦!

WebSocket是一种不同于HTTP的协议,重要的是它完美弥补了http协议在某些场合下的重大不足。接下来,我来简单介绍下websocket与http的区别。http/https请求是目前最广泛使用的网络通信协议,但是它们有一个非常大局限性,那就是请求只能由agent发起,server只能被动的等待请求,而且一次请求就是一个response和request对应。虽然在HTTP1.1中进行了改进,增加了keep-alive,出现了长连接这样的概念,但是仍然是一个request对应一个response,这在request中携带大量header信息,而response中没什么有用信息的时候,无疑是对通信资源的浪费。也许你觉得这么说有点抽象,那么我们举个例子来说明,我们在浏览器上用QQ聊天,如果浏览器作为agent使用的是http协议与server端通信,那么它需要定时去访问server(轮询),问它,喜欢的女神有没有回复我的信息啊。可是女神可能去洗澡了,手机没带进浴室,于是browser这个agent就不停的发一个大脑袋的request去server,每次拿回来的却都是干瘪瘪的response。这时候,如果你一边看电影一边等女神的回复,那么结果可能就是电影很卡,女神也没有消息。这个时候WebSocket协议就出现了。如果使用的是websocket协议,在登陆了网页版QQ之后,这个浏览器就会作为agent向server发起请求,建立一个连接,在这个连接建立期间,是可以进行双工通信的,就是说agent可以主动把消息发送给server,server也能在收到女神回复后,第一时间把消息传递到你的屏幕上,减少了无意义的轮询消耗,同时也保证了等女神回复期间电影不卡,不会无聊。甚至也可以简单的理解,只需要经过一次HTTP请求的连接建立,就可以进行源源不断的信息传送了。说到实现长连接,说白了,websocket的设计者在最初就是没想过像http协议那样谨慎小气,建立了连接说完一句话就跑。否则任何基于TCP的应用协议,都是可以进行长连接通信的。也许正是当初http的如此设计,才给了WebSocket如今的用武之地。以上是我的浅见,欢迎各位在下方评论区与我沟通交流。我是苏苏思量,来自BAT的Java开发工程师,每日分享科技类见闻,欢迎关注我,与我共同进步。

首先我们看一下websocket的出现背景,我们知道http系列协议是建立在tcp上的,理论上,他是可以可以双向通信的。但是http1.1之前,服务器没有实现推送的功能。每次都是客户端请求,服务器响应。下面看一下http协议关于请求处理的发展。http1.0的时候,一个http请求的生命周期是客户端发起请求,服务器响应,断开连接。但是我们知道tcp协议的缺点就是,三次握手需要时间,再加上慢开始等特性,每一个http请求都这样的话,效率就很低。http1.1的时候,默认开启了长连接(客户端请求中设置了keep-alive头),服务器处理一个请求后,不会立刻关闭连接,而是会等待一定的时间。如果没有请求才关闭连接。这样浏览器不仅可以在一个tcp连接中,不断地发送请求(服务器也会限制一个连接上可以处理的请求阈值),甚至可以一次发很多个请求。这就是http1.1的管道化(pipeline)技术。但是他也有个问题,因为对于基于http协议的客户端来说,虽然他可以发很多请求出去,但是当一个请求对于的回包回来时,他却无法分辨是属于哪个请求的。所以回包只能按请求顺序返回,这就引来了另一个问题-线头阻塞(Head-of-LinkBlocking)。并且http1.1虽然支持长连接,但是他不支持服务端推送(push)的能力。如果服务器有数据要给客户端,也只能等着客户端来取(pull)。来到了http2.0,不仅实现了服务器推送,还使用了帧(iframe),流(stream)等技术解决了线头阻塞的问题,http2.0在一个tcp连接中,可以同时发送多个http请求,每个请求是一个流,一个流可以分成很多帧,有了标记号,服务器可以随便发送回包,客户端收到后,根据标记,重新组装就可以。以上是http协议的关于请求的一些发展,而websocket就服务端推送提供了另外一种解决方案。他本质上是在tcp协议上封装的另一种应用层协议(websocket协议)。因为他是基于tcp的,所以服务端推送自然不是什么难题。但是在实现上,他并不是直接连接一个tcp连接,然后在上面传输基于websocket协议的数据包。他涉及到一个协议升级(交换)的过程。我们看看这个过程。1客户端发送协议升级的请求。在http请求加上下面的http头2服务器如果支持websocket协议的话,会返回101状态码表示同意协议升级,并且支持各种配置(如果服务器不支持某些功能或版本,或告诉客户端,客户端可以再次发送协议升级的请求)。服务会返回形如下面的http头(可以参考websocket协议)。3这样就完成了协议的升级,后续的数据通信,就是基于tcp连接之上,使用websocket协议封装的数据包。下面我们通过wireshark来了解这个过程。首先我们启动一个服务器(ip:192.168.8.226)。我们可以直接在浏览器控制台进行测试这时候,我们看看wireshark的包。首先看前面三条记录,这是tcp三次握手的数据包。这个我们都了解了,就不展示。接着看第四条记录。展开后如下。我们看到建立tcp连接后,浏览器发了一个http请求,并带上了几个websocket的数据包。接着看下面的一条。服务返回了同意升级协议或者说交换协议。从服务器代码中我们看到,在建立连接的时候我们给浏览器推送了一个getit的字符串。继续看上面的记录。这就是服务器给浏览器推送的基于websocket协议的数据包。具体每个字段什么意思,参考websocket协议就可以。继续往下看一条记录是针对服务器推送的数据包的一个tcp的ack。最后我们可以顺便看看最后三条写着keep-alive的记录。这就是之前文章里讲到的tcp层的keep-alive。因为我们一直没有数据传输,所以tcp层会间歇性地发送探测包。我们可以看看探测包的结构。有一个字节的探测数据。如果这时候我们发送一个数据包给服务器,又是怎样的呢。白色背景的三条数据,分别是浏览器发送给服务器的数据,服务器推送回来的数据。tcp的ack。我们发现,服务器给浏览器推送的时候,浏览器会发送ack,但是浏览器给服务器发送的时候,服务器貌似没有返回ack。下面我们看看为什么。首先我们看浏览器发出的包。再看看服务器给浏览器推送的数据包。我们发现服务器(tcp)推送消息的时候把ack也带上了。而不是发送两个tcp包。这就是tcp的机制。tcp不会对每个包都发ack,他会累积确认(发ack),以减少网络的包,但是他也需要保证尽快地回复ack,否则就会导致客户端触发超时重传。tcp什么时候发送确认呢?比如需要发送数据的时候,或者超过一定时间没有收到数据包,或者累积的确认数量达到阈值等。既然研究了tcp,我们不妨多研究点,我们看一下,如果这时候关闭服务器会怎样。服务器会发送一个重置包给浏览器,告诉他需要断开连接。继续,如果是浏览器自己调用close去关闭连接会怎样。我们看到websocket首先会发送一个FIN包给服务器,然后服务器也会返回一个FIN包,然后才开始真正的四次挥手过程。并且四次挥手的第一个fin包是服务器发的。我们再来看看安全版本的websocket。我们启动一个https服务器。然后在浏览器控制台执行。然后来看看wireshark。首先建立tcp连接,然后建立tls连接。后续的数据通信就可以基于加密来进行了。不再重复。后续分析tls协议的时候再分析。经过一系列的分析,我们对websocket协议应该有了更多的了解,最后再说一个关于websocket的点。我们发现如果在websocket连接上,一直不通信的话,websocket连接所维持的时间是依赖tcp实现的。因为我们发现tcp层会一直发送探测包。达到阈值之后,连接就会被断开。所以我们想维持websocket连接的话,需要自己去发送心跳包,比如ping,pong。总结:本文分析了websocket的基本原理,但不涉及协议的内容,如需了解协议的内容,可以参考rfc文档。