HTML5 中websocket长连接的具体实现方法

HTML5中通过调用与数据通信相关的Web Socket API,实现从服务器中推送信息到客户端。
Socket又称为套接字,是基于W3C标准开发在一个TCP接口中进行双向通信的技术。通常情况下,Socket用于描述IP地址和端口,是通信过程中的一个字符句柄。当服务器端又多个应用服务绑定一个Socket时,通过通信中的字符句柄,实现不同端口对应不同应用服务功能。目前,大部分浏览器都支持HTML5中Socket API的运行。

WebSocket连接服务器和客户端,这个链接是一个实时的长连接,服务器端一旦与客户端建立了双向链接,就可以将数据推送到Socket中,客户端只要有一个Socket绑定的地址和端口与服务器建立联系,就可以接收推送来的数据。

WebSocket API 的使用分为以下几个步骤:

步骤1、 创建连接,新建一个WebSocket对象十分的方便,代码如下:
var host = "ws://echo.websocket.org/";
var socket=new WebSocket(host);
注意:其中,URL必须以“ws”字符开头,剩余部分可以使用像HTTP地址一样来编写。该地址没有使用HTTP协议写法,因为它的属性为WebSocket URL;URL必须由4个部分组成,分别是通信标记(ws)、主机名称(host),端口号(port)及WebSocket Server.

步骤2,发送数据。当WebSocket对象与服务器建立联系后,使用如下代码发送数据:
socket.send(dataInfo);
注意:其中,objWs为新创建的WebSocket对象,send()方法中的dataInfo参数为字符类型,即只能使用文本数据或者将JSON对象转换成文本内容的数据格式。

步骤3,接收数据。客户端添加事件机制接收服务器发送来的数据,代码如下:
socket.onmessage=function(event){
    //弹出收到的信息
    alert(event.data);
    //其他代码
}

其中,通过回调函数中event对象的"data"属性来获取服务器端发送的数据内容,该内容可以是一个字符串或者JSON对象。

步骤4 状态标志。通过WebSocket对象的“readyState”属性记录连接过程中的状态值。
"readyState"属性是一个连接的状态标志,用于获取WebSocket对象在连接,打开,变比中和关闭时的状态。该状态标志共有4中属性值,如下表所示:


————————————————————————————————————
    属性值        属性常量        描述
————————————————————————————————————
    0        CONNECTING        连接尚未建立
    1        OPEN            WebSocket的链接已经建立
    2        CLOSING            连接正在关闭
    3        CLOSED            连接已经关闭或不可用
————————————————————————————————————

WebSocket对象在连接过程中,通过侦测这个状态标志的变化,可以获取服务器端与客户端连接的状态,并将连接状态已状态码形式返回给客户端。

步骤5 关闭socket连接。

socket.close();

可以把 WebSocket 看成是 HTTP 协议为了支持长连接所打的一个大补丁,它和 HTTP 有一些共性,是为了解决 HTTP 本身无法解决的某些问题而做出的一个改良设计。在以前 HTTP 协议中所谓的 keep-alive connection 是指在一次 TCP 连接中完成多个 HTTP 请求,但是对每个请求仍然要单独发 header;所谓的 polling 是指从客户端(一般就是浏览器)不断主动的向服务器发 HTTP 请求查询是否有新数据。这两种模式有一个共同的缺点,就是除了真正的数据部分外,服务器和客户端还要大量交换 HTTP header,信息交换效率很低。它们建立的“长连接”都是伪.长连接,只不过好处是不需要对现有的 HTTP server 和浏览器架构做修改就能实现。

WebSocket 解决的第一个问题是,通过第一个 HTTP request 建立了 TCP 连接之后,之后的交换数据都不需要再发 HTTP request了,使得这个长连接变成了一个真长连接。但是不需要发送 HTTP header就能交换数据显然和原有的 HTTP 协议是有区别的,所以它需要对服务器和客户端都进行升级才能实现。在此基础上 WebSocket 还是一个双通道的连接在同一个 TCP 连接上既可以发也可以收信息。此外还有 multiplexing 功能,几个不同的 URI 可以复用同一个 WebSocket 连接。这些都是原来的 HTTP 不能做到的。

另外说一点技术细节,因为看到有人提问 WebSocket 可能进入某种半死不活的状态。这实际上也是原有网络世界的一些缺陷性设计。上面所说的 WebSocket 真.长连接虽然解决了服务器和客户端两边的问题,但坑爹的是网络应用除了服务器和客户端之外,另一个巨大的存在是中间的网络链路。一个 HTTP/WebSocket 连接往往要经过无数的路由,防火墙。你以为你的数据是在一个“连接”中发送的,实际上它要跨越千山万水,经过无数次转发,过滤,才能最终抵达终点。在这过 程中,中间节点的处理方法很可能会让你意想不到。

比如说,这些坑爹的中间节点可能会认为一份连接在一段时间内没有数据发送就等于失效,它 们会自作主张的切断这些连接。在这种情况下,不论服务器还是客户端都不会收到任何提示,它们只会一厢情愿的以为彼此间的红线还在,徒劳地一边又一边地发送 抵达不了彼岸的信息。而计算机网络协议栈的实现中又会有一层套一层的缓存,除非填满这些缓存,你的程序根本不会发现任何错误。这样,本来一个美好的 WebSocket 长连接,就可能在毫不知情的情况下进入了半死不活状态。

而解决方案,WebSocket 的设计者们也早已想过。就是让服务器和客户端能够发送 Ping/Pong FrameRFC 6455 - The WebSocket Protocol)。这种 Frame 是一种特殊的数据包,它只包含一些元数据而不需要真正的 Data Payload,可以在不影响 Application 的情况下维持住中间网络的连接状

原文地址:https://www.cnblogs.com/wxmarr/p/4586548.html