不同的请求 用websocket 请求头建立连接吗

WebSocket 是什么原理?为什么可以实现持久连接?
我的图书馆
WebSocket 是什么原理?为什么可以实现持久连接?
以下是腾讯云技术社区整理的 ——众所周知,Web应用的通信过程通常是客户端通过浏览器发出一个请求,服务器端接收请求后进行处理并返回结果给客户端,客户端浏览器将信息呈现。这种机制对于信息变化不是特别频繁的应用可以良好支撑,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是Web应用经常面临的问题,比如金融证券的实时信息、Web导航应用中的地理位置获取、社交网络的实时消息推送等。传统的请求-响应模式的Web开发在处理此类业务场景时,通常采用实时通讯方案。比如常见的轮询方案,其原理简单易懂,就是客户端以一定的时间间隔频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步。其问题也很明显:当客户端以固定频率向服务器端发送请求时,服务器端的数据可能并没有更新,带来很多无谓请求,浪费带宽,效率低下。基于Flash,AdobeFlash通过自己的Socket实现完成数据交换,再利用Flash暴露出相应的接口给JavaScript调用,从而达到实时传输目的。此方式比轮询要高效,且因为Flash安装率高,应用场景广泛。然而,移动互联网终端上Flash的支持并不好:IOS系统中无法支持Flash,Android虽然支持Flash但实际的使用效果差强人意,且对移动设备的硬件配置要求较高。2012年Adobe官方宣布不再支持Android4.1+系统,宣告了Flash在移动终端上的死亡。传统的Web模式在处理高并发及实时性需求的时候,会遇到难以逾越的瓶颈,需要一种高效节能的双向通信机制来保证数据的实时传输。在此背景下,基于HTML5规范的、有Web TCP之称的 WebSocket应运而生。早期HTML5并没有形成业界统一的规范,各个浏览器和应用服务器厂商有着各异的类似实现,如IBM的MQTT、Comet开源框架等。直到2014年,HTML5终于尘埃落地,正式落实为实际标准规范,各个应用服务器及浏览器厂商逐步开始统一,在 JavaEE7中也实现了WebSocket协议。至此无论是客户端还是服务端的WebSocket都已完备。用户可以查阅,熟悉新的HTML协议规范及WebSocket支持。WebSocket 机制以下简要介绍一下WebSocket的原理及运行机制。WebSocket是HTML5下一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的。它与HTTP一样通过已建立的TCP连接来传输数据,但是它和HTTP最大不同是:WebSocket是一种双向通信协议。在建立连接后,WebSocket服务器端和客户端都能主动向对方发送或接收数据,就像Socket一样;WebSocket需要像TCP一样,先建立连接,连接成功后才能相互通信。传统HTTP客户端与服务器请求响应模式如下图所示:WebSocket模式客户端与服务器请求响应模式如下图:上图对比可以看出,相对于传统HTTP每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket是类似Socket的TCP长连接通讯模式。一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端中断连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。相比HTTP长连接,WebSocket有以下特点:是真正的全双工方式,建立连接后客户端与服务器端是完全平等的,可以互相主动请求。而HTTP长连接基于HTTP,是传统的客户端对服务器发起请求的模式。HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,信息交换效率很低。Websocket协议通过第一个request建立了TCP连接之后,之后交换的数据都不需要发送 HTTP header就能交换数据,这显然和原有的HTTP协议有区别所以它需要对服务器和客户端都进行升级才能实现(主流浏览器都已支持HTML5)。此外还有 multiplexing、不同的URL可以复用同一个WebSocket连接等功能。这些都是HTTP长连接不能做到的。下面再通过客户端和服务端交互的报文对比WebSocket通讯与传统HTTP的不同点:在客户端,new WebSocket实例化一个新的WebSocket客户端对象,请求类似 ws://yourdomain:port/path 的服务端WebSocket URL,客户端WebSocket对象会自动解析并识别为WebSocket请求,并连接服务端端口,执行双方握手过程,客户端发送数据格式类似:GET /webfin/websocket/ HTTP/1.1Host: localhostUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==Origin: http://localhost:8080Sec-WebSocket-Version: 13可以看到,客户端发起的WebSocket连接报文类似传统HTTP报文,Upgrade:websocket参数值表明这是WebSocket类型请求,Sec-WebSocket-Key是WebSocket客户端发送的一个 base64编码的密文,要求服务端必须返回一个对应加密的Sec-WebSocket-Accept应答,否则客户端会抛出Error during WebSocket handshake错误,并关闭连接。服务端收到报文后返回的数据格式类似:HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=Sec-WebSocket-Accept的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,HTTP/1.1 101 Switching Protocols表示服务端接受WebSocket协议的客户端连接,经过这样的请求-响应处理后,两端的WebSocket连接握手成功, 后续就可以进行TCP通讯了。用户可以查阅了解WebSocket客户端和服务端更详细的交互数据格式。在开发方面,WebSocket API 也十分简单:只需要实例化 WebSocket,创建连接,然后服务端和客户端就可以相互发送和响应消息。在WebSocket 实现及案例分析部分可以看到详细的 WebSocket API 及代码实现。腾讯云公网有日租类型七层负载均衡转发部分支持Websocket,目前包括英魂之刃、银汉游戏等多家企业已接入使用。当出现不兼容问题时,请修改websocket配置,websocket server不校验下图中圈出的字段:一个使用WebSocket应用于视频的业务思路如下:使用心跳维护websocket链路,探测客户端端的网红/主播是否在线设置负载均衡7层的proxy_read_timeout默认为60s设置心跳为50s,即可长期保持Websocket不断开近期Websocket将开放自定义配置,敬请期待。相关阅读推荐
TA的推荐TA的最新馆藏[转]&
喜欢该文的人也喜欢理解Websocket - 有趣的灵魂 - CSDN博客
理解Websocket
【Swoole】
【Network】
HTTP特点:
限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。
现在,很多网站为了实现服务器推技术,通常的解决办法是使用客户端(浏览器)做AJAX轮询
什么是AJAX轮询?
浏览器每间隔一定时间向服务器发送AJAX请求,询问是否有新的数据,如果有,则返回给客户端。一般像下面的代码这样(JQuery描述)
var link={        
//AJAX执行的配置对象
type:"GET",      
//设置请求方式,默认为GET,
async:true,      
//设置是否异步,默认为异步
url:"getNewData.php",
//请求的链接
dataType:"json",    //设置数据的返回格式
success:function (msg){
   //在这里处理返回的数据
  setTimeout("link()",300);//每隔0.3s建立一次新的请求
}//成功时的回调函数
$.ajax(link);          //执行ajax请求。
这样会引发什么问题?
浏览器需要不断的向服务器发出请求,然而HTTP request的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源。
比较新的技术去做轮询的效果是Comet,Comet有两种常用的方式:
基于AJAX long-polling
基于 Iframe 及 htmlfile 的流(streaming)
基于AJAX long-polling与传统的 AJAX 应用不同之处:
服务器端会阻塞请求直到有数据传递或超时才返回。
客户端 JavaScript响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
基于 Iframe 及 htmlfile 的流(streaming)
iframe 是很早就存在的一种 HTML 标记, 通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
尽管Comet这种技术可达到双向通信,但依然需要发出请求,而且在Comet中,普遍采用了长链接,这也会大量消耗服务器带宽和资源。
面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。
什么是WebSocket?
一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 是独立的、创建在 TCP 上的协议,和 HTTP 的唯一关联是使用 HTTP 协议的101状态码进行协议切换,使用的 TCP 端口是80,可以用于绕过大多数防火墙的限制。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端直接向客户端推送数据而不需要客户端进行请求,在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并允许数据进行双向传送。
服务器与客户端之间交换的数据包档头很小,大概只有2字节。(早期版本7.0)
今天使用swoole写了基于Websocket的聊天室,正好用来作为例子
浏览器请求
服务器响应
在请求中的“Sec-WebSocket-Key”是随机的,服务器端会用这些数据来构造出一个SHA-1的信息摘要。
把“Sec-WebSocket-Key”加上一个魔幻字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”。使用SHA-1加密,之后进行BASE-64编码,将结果做为“Sec-WebSocket-Accept”头的值,返回给客户端。
我的热门文章Posts - 13,
Articles - 1,
Comments - 33
22:59 by OshynSong, ... 阅读,
Websocket协议是为了解决web即时应用中服务器与客户端浏览器全双工通信的问题而设计的,是完全意义上的Web应用端的双向通信技术,可以取代之前使用半双工HTTP协议而模拟全双工通信,同时克服了带宽和访问速度等的诸多问题。协议定义为ws和wss协议,分别为普通请求和基于SSL的安全传输,占用端口与http协议系统,ws为80端口,wss为443端口,这样可以支持HTTP代理。
协议包含两个部分,第一个是&握手&,第二个是数据传输。
一、Websocket URI
定义的两个协议框架ws和wss与http类似,而且各自部分的要求也是在HTTP协议中使用的一样,各自的URI如下:
ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]& & & & wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
其中port是可选项,query前接&?&。
二、握手(Opening & Closing Handshake)打开连接
当建立一个Websocket连接时,为了保持基于HTTP协议的服务器软件和中间件进行兼容工作,客户端打开一个连接时使用与HTTP连接的同一个端口到服务器进行连接,这样被设计为一个升级的HTTP请求。
1、发送握手请求
此时的连接状态是CONNECTING,客户端需要提供host、port、resource-name和一个是否是安全连接的标记,也就是一个WebSocket URI。
客户端发送的一个到服务器端握手请求如下:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
这个升级的HTTP请求头中的字段顺序是可以随便的。与普通HTTP请求相比多了一些字段。
Sec-WebSocket-Protocol:字段表示客户端可以接受的子协议类型,也就是在Websocket协议上的应用层协议类型。上面可以看到客户端支持chat和superchat两个应用层协议,当服务器接受到这个字段后要从中选出一个协议返回给客户端。
Upgrade:告诉服务器这个HTTP连接是升级的Websocket连接。
Connection:告知服务器当前请求连接是升级的。
Origin:该字段是用来防止客户端浏览器使用脚本进行未授权的跨源攻击,这个字段在WebSocket协议中非常重要。服务器要根据这个字段判断是否接受客户端的Socket连接。可以返回一个HTTP错误状态码来拒绝连接。
Sec-WebSocket-Key:为了表示服务器同意和客户端进行Socket连接,服务器端需要使用客户端发送的这个Key进行校验,然后返回一个校验过的字符串给客户端,客户端验证通过后才能正式建立Socket连接。服务器验证方法是:首先进行 Key + 全局唯一标示符(GUID)&258EAFA5-E914-47DA-95CA-C5AB0DC85B11&连接起来,然后将连接起来的字符串使用SHA-1哈希加密,再进行base64加密,将得到的字符串返回给客户端作为握手依据。其中GUID是一个对于不识别WebSocket的网络端点不可能使用的字符串。
发送请求的要求:
请求的WebSocket URI必须要是定义的有效的URI。
如果客户端已经有一个WebSocket连接到远程服务器端,不论是否是同一个服务器,客户端必须要等待上一个连接关闭后才能发送新的连接请求,也就是同一客户端一次只能存在一个WebSocket连接。如果想同一个服务器有多个连接,客户端必须要串行化进行。如果客户端检测到多个到不同服务器的连接,应该限制一个最大连接数,在web浏览器中应该设定最多可以打开的标签页的数目。这样可以防止到远程服务器的DDOS攻击,但这是对到多个服务器的连接,如果是到同一个服务器连接,并没有数目限制。
如果使用了代理服务器,那么客户端建立连接的时候需要告知代理服务器向目标服务器打开TCP连接。
如果连接没有打开,一定是某一方出现错误,此时客户端必须要关闭再次连接的尝试。
连接建立后,握手必须要是一个有效的HTTP请求
请求的方式必须是GET,HTTP协议的版本至少是1.1
Upgrade字段必须包含而且必须是"websocket",Connection字段必须内容必须是&Upgrade&
Sec-Websocket-Version必须,而且必须是13
2、返回握手应答
服务器返回正确的相应头后,客户端验证后将建立连接,此时状态为OPEN。服务器响应头如下:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
响应头握手过程中是服务器返回的是否同意握手的依据。
首行返回的是HTTP/1.1协议版本和状态码101,表示变换协议(Switching Protocol)
Upgrade 和 Connection:这两个字段是服务器返回的告知客户端同意使用升级并使用websocket协议,用来完善HTTP升级响应
Sec-WebSocket-Accept:服务器端将加密处理后的握手Key通过这个字段返回给客户端表示服务器同意握手建立连接。
Sec-Websocket-Procotol:服务器选择的一个应用层协议。
上述响应头字段被客户端浏览器解析,如果验证到Sec-WebSocket-Accept字段的信息符合要求就会建立连接,同时就可以发送WebSocket的数据帧了。如果该字段不符合要求或者为空或者HTTP状态码不为101,就不会建立连接。
服务器端响应步骤:
解析握手请求头:获取握手依据Key并进行处理,检测HTTP的GET请求和版本是否准确,Host字段是否有权限,Upgrade字段中websocket是一个与大小写无关的ASCII字符串,Connection字段是一个大小写无关的"Upgrade"ASCII字符串,Websocket协议版本必须为13,其他的关于Origin、Protocol和Extensions可选。
发送握手响应头:检测是否是wss协议连接,如果是就是用TLS握手连接,否则就是普通连接。服务器可以添加额外的验证信息到客户端进行验证。当进行一系列验证之后,服务器必须返回一个有效的HTTP响应头。响应头中每一行一个字段,结束必须为&\r\n&,使用的ABNF语法。
除了上述必要头字段之外,其他的HTTP协议定义的字段都可以使用,如Set-Cookie等。在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
我利用websocket建立了一个聊天室,这个聊天室有两个页面,假如对面发送的消息是1,我在第一个页面接收,假如对面发送的消息是2,我在第二个页面接受,请问这个如何实现?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
不确定你这种聊天室?
通常意义上的聊天室是 多个客户端连接服务器进行通信,服务器再把客户端的消息广播给连接的客户端。
例如 一个server,三个client A,B,C
A, B, C 分别建立三个 websocket 连接 server
当 A 发消息1给 server, server 再分别给 B, C 广播,也就是推送给 B,C。于此类似,B 发消息2到 server,server 再转发给 A,C。
题主说的聊天是 A 和 B 之间直接通信么?也就是在广播和连接中再做filter处理了
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
client和client通信不是该用WebRTC么
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
以前碰到过这样的需要,可参考lightstreamer的实现:
我也不明白它们的实现原理,不过它确实实现了这样的效果.
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:

我要回帖

更多关于 websocket 请求头 的文章

 

随机推荐