
WebSocket是双向的,一种全双工协议,用于客户端-服务器通信的场景。定义了在web浏览器和服务器之间建立“Socket套接字”连接的API从而摆脱HTTP的限制。
如何建立WebSocket连接的:
1、发送HTTP,GET请求
通过特殊的GET请求,表示它想将连接从HTTP协议升级到WebSocket。
GET wss://example.com:8181/ HTTP/1.1
Host: localhost: 8181
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: zy6Dy9mSAIM7GJZNf9rI1A==2、服务端响应HTTP 101状态码
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Sec-WebSocket-Accept: EDJa7WCAQQzMCYNJM42Syuo9SqQ=
Upgrade: websocket3、 进行websocket通信
前两步传输HTTP的TCP连接,就被用来websocket通信了
解释下相关的HTTP Heater 头:
头 | 必需 | 描述 |
|---|---|---|
Host | 是 | 请求所发送到的服务器的主机名和端口号(端口可选)。 |
Connection | 是 | 表示客户端希望协商更改连接的使用方式。值必须为Upgrade。服务器也会返回同样的内容。 |
Sec-WebSocket-Version | 是 | 唯一可接受的值是13。此标头中传递的任何其他版本都无效。 |
Sec-WebSocket-Key | 是 | 客户端发送的base64编码的一次性随机值(nonce)。大多数WebSocket库或使用浏览器类会自动为您处理。 |
Sec-WebSocket-Accept | 是 | 服务器作为对Sec-WebSocket密钥的直接响应返回的base64编码的SHA-1哈希值。 表示服务器愿意启动WebSocket连接。 |
Sec-WebSocket-Protocol | 否 | 包含一个值列表,指示客户端想要使用哪些子协议,按偏好排序。 服务器需要在响应中包含此字段以及一个选定的子协议值(列表中支持的第一个)。 |
Sec-WebSocket-Extensions | 否 | 可选的标头字段,最初从客户端发送到服务器,然后从服务器发送到客户端。 它有助于客户端和服务器就一组协议级扩展达成一致,以便在连接期间使用。 |
Origin | 否 | 所有浏览器客户端发送的标头字段(非浏览器客户端可选)。 用于防止web浏览器中使用WebSocket API的脚本对WebSocket服务器进行未经授权的交叉使用。如果服务器不接受所指示的源,则连接将被拒绝。 |
Python示例:
pip install websockets服务端:
#!/usr/bin/env python
import asyncio
from websockets.server import serve
async def echo(websocket):
async for message in websocket:
await websocket.send(message)
async def main():
async with serve(echo, "localhost", 8765):
await asyncio.get_running_loop().create_future() # run forever
asyncio.run(main())客户端:
(当然可以通过浏览器,用js发起)
#!/usr/bin/env python
from websockets.sync.client import connect
def hello():
with connect("ws://localhost:8765") as websocket:
websocket.send("Hello world!")
message = websocket.recv()
print(f"Received: {message}")
hello()