html5 http的轮询和Websocket原理

一、HTTP的轮询 Web客户端与服务器之间基于Ajax(http)的常用通信方式,分为 短连接 与 长轮询 。 短连接:客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。 长轮询:客户端像传统轮询一样从服务器请求数据。然而,如果服务器没有可以立即返回给客户端的数据,则不会立刻返回一个空结果,而是保持这个请求等待数据到来(或者恰当的超时:小于ajax的超时时间),之后将数据作为结果返回给客户端。 长轮询机制如下图所示: 二、Websocket基本概念 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。 在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。 现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。 HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。 当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。 三、Websocket 握手原理: Websocket的握手原理大致可分为以下步骤: 第一步:客户端发起HTTP请求连接 第二步:服务端从请求头中取出Sec-WebSocket-Key的值 第三步:给Sec-WebSocket-Key值 拼接一个magic_string 的到一个新的value 第四步:给新的value先做 sha1加密 再做 base64加密 第五步:拼接一个响应头 第六步:服务器将拼好的响应头发送给客户端 第七步:客户端解密Sec-WebSocket-Accept得到Sec-WebSocket-Key判断是否握手成功 代码实现: import socket,base64,hashlib # 创建socket连接 sock = socket.socket(socket.AF_INET,socket.soCK_STREAM) # 绑定端地址和口号 sock.bind(('127.0.0.1',9527)) # 监听 sock.listen(5) # 获取客户端socket对象 conn,address = sock.accept() # 获取客户端的【握手】信息 data = conn.recv(1024) print(data) def get_headers(data): """从请求头中取出Sec-WebSocket-Key对应的值并返回""" header_dict = {} header_str = data.decode("utf8") for i in header_str.split("\r\n"): if str(i).startswith("Sec-WebSocket-Key"): return i.split(":")[1].strip() # 得到Sec-WebSocket-Key对应的值 ws_key = get_headers(data) # 魔法字符串magic string为:258EAFA5-E914-47DA-95CA-C5AB0DC85B11 magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' # 拼接 socket_str = ws_key + magic_string # sha1加密 socket_str_sha1 = hashlib.sha1(socket_str.encode("utf8")).digest() # base64加密 socket_str_base64 = base64.b64encode(socket_str_sha1) # 拼接响应头 response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \ "Upgrade:websocket\r\n" \ "Connection: Upgrade\r\n" \ "Sec-WebSocket-Accept: %s\r\n" \ "WebSocket-Location: ws://127.0.0.1:9527\r\n\r\n" % (socket_str_base64.decode("utf8")) # 服务器发送响应头到客户端 conn.send(response_tpl.encode("utf8")) # 客户端服务端建立长连接循环接收发送数据 while True: msg = conn.recv(8096) print(msg)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我正在使用一个返回PNG编码的base64字符串的插件,我无法更改它,我必须使用它,但是我真正需要的是tiff编码值(base-64).有办法吗?我试图创建一个画布,加载pngbase64,然后使用toDataURL(‘image/tiff’),但经过一些研究,我发现不支持tiff作为toDataURL()的输出.有什么建议么?解决
我有这个正在玩的浏览器游戏.但是我也在尝试使其也可以在移动浏览器中使用.但是当同时按下多个按钮时,我似乎无法使其正常工作.我有这个游戏,您可以左右移动并跳跃.(见下图)touchbuttonsingamehttp://www.userhome.org/mobilegame.png我的代码如下所示:functioninittouc
我正在使用d3.js进行散点图绘制,我想绘制x和y轴以使其在点(100,75)相交.如何做到这一点?我在用svg.append("g").attr("class","axis").attr("transform","translate(0,"+(padding+223)+")").call(xAxis2);//CreateY2ax
我在htmlimg标签中有一张图片.我的要求是,当用户单击图像时,它将在拖动鼠标的同时标记一个点并画一条线.然后,当用户完成拖动并单击图像时,它应该显示的线条还以毫米/厘米为单位显示线条的尺寸.即,用户必须在图像上画一条线并显示其画线的距离/长度(以毫米/厘米为单位).如何在Web
我正在开发智能电视应用程序,并且从IP摄像机流媒体直播视频是该功能的很大一部分.相机手册指出,如果将其设置为流MPEG-4或H.264,则不支持HTTP.只有RTSP/RTP.替代方法(通过HTTP)是MotionJPEG,我希望尽可能避免这种情况(电视上的帧速率糟透了).是否有用于RTSP的JavaScript/HT
遵循ControlstartpositionanddurationofplayinHTML5video的原则,我尝试使每个片段播放完后自动将视频从一个片段跳到下一片段.每个片段的持续时间相同,每个片段的开始时间位于一个数组中.我似乎无法弄清楚如何在addEventListener之后循环遍历数组.varvideo=document
我正在尝试将相当简单的html导出到canvas,然后导出到png.为此,我正在使用rasterizeHTML(http://cburgmer.github.ioasterizeHTML.js/).我面临的问题是,我收到一条警告,例如正在加载外部图像/资源,但我没有.这是我尝试过的:HTML:<canvasheight="500"width="500"id="rasterize
Thisjsfiddledemonstratesthefollowingissue.最简单的示例是:<inputid="number"type="number"value="1">console.log(document.getElementById('number').value);这将按预期记录1.但是,这:<inputid="number"type
我正在使用Spring表单,并且想使用Spring表单似乎不支持的HTML5‘required’属性.<form:inputpath="someinput"cssClass="required"/>我似乎做不到<form:inputpath="someinput"cssClass="required"required="required"/>因为Spring
我正在使用angularJS开发应用程序.我的应用程序要求将数据保存在本地.因此,我正在使用HTML5本地存储.HTML5本地存储的问题在于,当用户清除浏览数据时,所有数据都将丢失,我们需要避免这种情况.我意识到,由于数据存储在用户计算机上,因此无法100%保护数据.本质上,是否有一种方法可以
我希望在首次加载时在我的网站上预加载一些小视频文件.这样,当用户单击以进入网站的一部分时,可以自动播放和使用它们.我需要无缝过渡,因此理想情况下应预加载整个视频文件,以免造成任何延迟.香港专业教育学院尝试了一些不同的插件,如html5preloader,以及其他一些JS技术将视频文件
 指引表单在网页应用中十分重要,基本上任何一个网站都必须使用到表单元素,所以表单的美观和易于交互对于网站设计就变得十分重要。HTML5对目前Web表单进行了全面提升,使得我们使用表单更加智能。它在保持了简单易用的特性的同时,还增加了许多内置的控件或者控件属性来满足用户的需
我正在学习JavaScript,但经验不足.但是我正在制作一个HTML表,我想在每个表单元格(<td>)中添加一个onClick事件.<tableid="1"><tr><tdonClick="tes()">1<d><tdonClick="tes()">2<d><r><tr
我正在使用AngularJS,并且在选择数据列表(html5)的元素时要使用指令ng-click.这是我的实际代码示例:<label>Search</label><inputtype="text"class="input-search"list="datalistcit"ng-change="changeQuery(queryCity)"ng-model="queryC
当您将来自其他域的图像放在画布中时,画布会受到污染,并且诸如getDataURL或getImageData之类的某些功能会被禁用.当您尝试使用此类功能时,会发生SECURITY_ERROR错误.为什么有这种保护措施?这种方法使用了哪种攻击?谢谢!编辑:我应该问:如何将来自其他域的图像用于攻击?   我弄不
我写了这个webRTC应用程序,它使用添加了不同滤镜的照片进行拍摄.当我单击“单击”按钮时,来自webRTC视频提要的帧将被加载到右侧的画布上.HTML代码-<videoid="vid"autoplay="true"></video><canvasid="cvs"></canvas><buttonid="btn1"onclick="start(
如果Chrome中使用了网络摄像头,则该页面的标签上会出现一个红点.并且,如果其他页面尝试访问网络摄像头,视频将变黑.我的问题是,是否可以使用JavaScript检查是否正在使用网络摄像头?怎么样?通过使用navigator.getUserMedia,我尝试了以下代码:navigator.getUserMedia=navigator.get
好的,所以我发现使用JqueryMobile和Phonegap开发androidApp在android4中工作正常,但是在旧版本(例如2.2.2)上,可滚动功能中断.因此,我尝试使用iScroll,但是存在冲突的问题,最终我只是决定编写一个Javascript函数来处理它.它曾经可以工作,但是现在坏了.所以这里是:<!DOCTYPEHT
我有一个正在构建的Webapp,并且刚开始使用SQLite.我已经能够创建表单,打开我创建的数据库,创建表和所需的字段以及在字段中输入数据.现在,我尝试使用SELECT语句读回数据,以将其显示在屏幕上以及列的列表中.我只是不知道javascript或HTML5中的SELECTstatemnt的语法‘SELECT*FRO
这些是我正在开发的表单的屏幕截图.我要设计表单中的选择框,以使选项中的文本右对齐,并且在选择选项后,所显示的所选文本也应显示如下图所示.HTML代码:<select><optionvalue="0"selected="selected"style="text-align:right;">EqualsTo</option><optionvalue="1&quo