资讯专栏INFORMATION COLUMN

浅析websocket

oujie / 2928人阅读

摘要:握手结束后,双方就可以进行双向通讯了,所有的通讯内容都以数据帧格式来传输。数据帧比特表示一个中的最后一个。每个比特必须为,后续扩展使用。比特表示负载数据是否。或者字节如果标志为时存在,保存。

Websocket 背景

历史上,如果一个web应用程序需要和server进行双向通信(例如,实时聊天和游戏),
需要大量的http请求来检查server的内容是否有更新, 同时也需要很多http请求来发送
通知,这种方式有许多问题:

server端必须使用大量的tcp连接来服务每一个client:一类连接用来发送信息给
client, 另一类连接用来接收新的消息。

有大量不必要网络开销,因为每一次消息通讯都都包含http header。

client需要维护一个map来映射发送数据的连接和接受数据的连接。

一个简单的解决方案就是使用一个tcp连接来进行双向通讯,这就是websocket的作用。

websocket使用80和443端口,对HTTP代理和网关友好。

连接握手过程

client发送

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

server响应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

连接握手的目的是兼容基于HTTP的server和代理,所以一个端口可以同时服务HTTP请求和
websocket请求。

请求中Upgrage: websocket表示这是一个websocket请求。服务端收到该请求后会根据
请求中携带的Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==通过特定算法生成
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=响应给客户端,客户端校验
通过握手成功。

握手结束后,双方就可以进行双向通讯了,所有的通讯内容都以数据帧格式来传输。

数据帧

FIN: 1比特

表示一个message中的最后一个frame。

RSV1, RSV2, RSV3: 每个1比特

必须为0,后续扩展使用。

Optcode: 4比特

定义负载数据的解析方式。

%x0 表示一个连续帧。

%x1 表示一个文本帧。

0x2 表示一个二进制帧。

0x3-7 保留,以后给非控制帧使用。

0x8 表示连接关闭。

0x9 表示ping。

0xA 表示pong。

0xB-F 保留,以后给控制帧使用。

Mask: 1比特

表示负载数据是否masked。如果为1,masking-key包含一个key,用来unmask负载
数据。所有从客户端方向发送的数据,该位必须置1。

*Playload length: * 7比特,7+16比特, 或者7+64比特

0-125表示负载数据的长度。

126,接下来的两个字节为16位无符号整型表示负载数据长度。

127, 接下来的8个字节为64为无符号整型表示负载数据长度。

Masking key: 0或者4字节

如果mask标志为1时存在,保存mask key。

Payload data: 负载数据。

关闭握手过程

关闭握手比连接握手简单的多,连接的任何一端都可以发送一个close frame,
开始关闭握手,收到这个control frame的端发送一个close frame响应,
另一端收到这个close frame后关闭连接。

一端发送close frame后就表示这个连接将会被关闭并且不会再发送任何数据到另一端, 对端
收到close frame后知道这个连接将会被关闭,后续收到的数据都会被丢弃。

websocket关闭握手的目的是完善TCP的关闭握手,因为在端到端的情景TCP的关闭握手并不
总是可信赖的,尤其端到端中间有代理或者防火墙的情况下。

通过发送一个close frame然后等待响应,这种方式避免了不必要的数据丢失。

websocket & nginx

nginx并没有支持websocket,只是支持websocket的代理。

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        "" close;
    }

    upstream websocket {
        server 192.168.100.10:8010;
    }

    server {
        listen 8020;
        location / {
            proxy_pass http://websocket;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    }
}

nginx也有第三方支持websocket的模块nchan,但
不是为流媒体设计的。

哪些服务端支持websocket

Node.js

Socket.IO

WebSocket-Node

ws

Java

Jetty

Rubby

EventMachine

Python

pywebsocket

Tornado

Erlang

Shirasu

.NET

SuperWebSocket

参考资料

http://blog.teamtreehouse.com/an-introduction-to-websockets

http://www.websocket.org/aboutwebsocket.html

https://www.html5rocks.com/en/tutorials/websockets/basics

https://os.alfajango.com/websockets-slides/#/2

The WebSocket Protocol

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38246.html

相关文章

  • 浅析websocket

    摘要:握手结束后,双方就可以进行双向通讯了,所有的通讯内容都以数据帧格式来传输。数据帧比特表示一个中的最后一个。每个比特必须为,后续扩展使用。比特表示负载数据是否。或者字节如果标志为时存在,保存。 Websocket 背景 历史上,如果一个web应用程序需要和server进行双向通信(例如,实时聊天和游戏),需要大量的http请求来检查server的内容是否有更新, 同时也需要很多http请...

    fou7 评论0 收藏0
  • React Native Debug原理浅析

    摘要:过程涉及到三个对象,一个是或,一个是,另外一个就是浏览器或或其他。在中进行配置了,也就是会执行脚本。然后会给这个注册一些监听在收到消息时会回调。发出一个消息让浏览器准备的运行环境在收到消息会调用。 第一次在segmentfault写博客,很紧张~~~公司项目上ReactNative,之前也是没有接触过,所以也是一边学习一边做项目了,最近腾出手来更新总结了一下RN的Debug的一个小知识...

    senntyou 评论0 收藏0
  • React Native Debug原理浅析

    摘要:过程涉及到三个对象,一个是或,一个是,另外一个就是浏览器或或其他。在中进行配置了,也就是会执行脚本。然后会给这个注册一些监听在收到消息时会回调。发出一个消息让浏览器准备的运行环境在收到消息会调用。 第一次在segmentfault写博客,很紧张~~~公司项目上ReactNative,之前也是没有接触过,所以也是一边学习一边做项目了,最近腾出手来更新总结了一下RN的Debug的一个小知识...

    avwu 评论0 收藏0
  • WebSocket系列之基础知识入门篇

    摘要:概述本文是系列的第一篇,主要介绍相关的基础协议知识和。客户端收到响应后,立即发起下一次的请求。收到消息通过事件来接收消息。类型则需要传递一个对象作为参数,相关的内容也将在本系列第二篇中进行介绍。 概述 本文是WebSocket系列的第一篇,主要介绍WebSocket相关的基础协议知识和API。由于WebSocket的相关介绍在MDN中分布较乱,初学者不太容易入门,因此通过本文将相关基础...

    Yuqi 评论0 收藏0
  • 原理解释 - 收藏集 - 掘金

    摘要:巧前端基础进阶全方位解读前端掘金我们在学习的过程中,由于对一些概念理解得不是很清楚,但是又想要通过一些方式把它记下来,于是就很容易草率的给这些概念定下一些方便自己记忆的有偏差的结论。 计算机程序的思维逻辑 (83) - 并发总结 - 掘金从65节到82节,我们用了18篇文章讨论并发,本节进行简要总结。 多线程开发有两个核心问题,一个是竞争,另一个是协作。竞争会出现线程安全问题,所以,本...

    AlphaGooo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<