websocket为啥只需一次握手

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了websocket为啥只需一次握手相关的知识,希望对你有一定的参考价值。

参考技术A RFC 6455规定的就是一次握手。
至于WebSocket基于TCP的问题,底层TCP的三次握手对于上层的WebSocket是透明的。
参考技术B WebSocket是基于TCP的,TCP的握手和WebSocket的握手是不同层次的。
TCP的握手用来保证链接的建立,WebSocket的握手是在TCP链接建立后告诉服务器这是个WebSocket链接,服务器你要按WebSocket的协议来处理这个TCP链接。

websocket协议

传统的http协议有个缺点,就是只能由客户端不断地主动发起请求,服务端才把信息返回到客户端,服务端是不会主动给客户端发消息的,这就是传统的单向请求,

而websocket是双向的,在单个 TCP 连接上进行全双工通讯,前后端会有一次握手,握手一旦成功后,只要有消息,服务端就会实时的推送给客户端,客户端不需要每一次去发问,WebSocket 只需要建立一次连接,就可以一直保持连接状态。这相比于轮询方式的不停建立连接显然效率要大大提高。

以下是websocket的一些特点

(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

技术图片

在服务端
WebSocket 在服务端的实现非常丰富。Node.js、Java、C++、Python 等多种语言都有自己的解决方案。
基于多线程或多进程的服务器无法适用于 WebSockets,因为它旨在打开连接,尽可能快地处理请求,然后关闭连接。任何实际的 WebSockets 服务器端实现都需要一个异步服务器。
WebSocket 代理
如果把 WebSocket 的通信看成是电话连接,Nginx 的角色则像是电话接线员,负责将发起电话连接的电话转接到指定的客服。

Nginx 从 1.3 版开始正式支持 WebSocket 代理。如果你的 web 应用使用了代理服务器 Nginx,那么你还需要为 Nginx 做一些配置,使得它开启 WebSocket 代理功能。

以下为参考配置:

server {
  // this section is specific to the WebSockets proxying
  location /socket.io {
    proxy_pass http://app_server_wsgiapp/socket.io;
    proxy_redirect off;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 600;
  }
}

在客户端
创建 WebSocket 对象。

var Socket = new WebSocket(url, [protocol] );
以上代码中的第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议

WebSocket对象的2个属性(都是只读)

readyState bufferedAmount

WebSocket对象的4个事件

open message error close

WebSocket对象的2个方法

send() close()

示例

// 初始化一个 WebSocket 对象
var ws = new WebSocket(‘ws://localhost:9998/echo‘);

// 建立 web socket 连接成功触发事件
ws.onopen = function() {
// 使用 send() 方法发送数据
ws.send(‘发送数据‘);
alert(‘数据发送中...‘);
};

// 接收服务端数据时触发事件
ws.onmessage = function(evt) {
var received_msg = evt.data;
alert(‘数据已接收...‘);
};

// 断开 web socket 连接成功触发事件
ws.onclose = function() {
alert(‘连接已关闭...‘);
};

兼容问题

使用之前看浏览器是否支持websocket协议
对于低端不支持websocket的浏览器,一般有几个解决方案
//判断浏览器是否支持websocket 支持返回true
function check_support_websocket() {
return typeof WebSocket != ‘undefined‘;
}

1.使用轮询或长连接的方式实现伪websocket的通信

2.使用flash或其他方法实现一个websocket客户端 :https://segmentfault.com/q/1010000005000671/a-1020000005003936

https://blog.csdn.net/u011925826/article/details/17532465

以上是关于websocket为啥只需一次握手的主要内容,如果未能解决你的问题,请参考以下文章

websocket协议握手详解

websock第一次连不上window

HTML5 - Websocket

HTML5 WebSocket

为啥客户端不接受我的 WebSocket 响应握手?

如何编写自己的 TCP/IP 或 ISO/OSI 堆栈以使用 WebSockets 而无需每次都使用握手?