赞
踩
WebSocket是一种在Web应用程序中实现实时双向通信的协议。它允许在客户端和服务器之间建立持久性连接,使得双方可以通过该连接进行长时间的数据传输。
WebSocket协议位于应用层,它提供了一种基于TCP协议的全双工通信机制,WebSocket在建立连接时依赖HTTP/HTTPS协议。
WebSocket的主要用途是实现实时的双向通信。它可以用于许多不同类型的应用,包括但不限于:
WebSocket 支持以下几种通信模式:
优点 | 缺点 |
---|---|
实现了实时双向通信 | 不支持跨域通信 |
具有较低的网络开销和较高的实时性 | 部分浏览器和网络设备可能不支持 WebSocket |
简单易用,易于集成到现有的 Web 应用中 | 需要额外的服务器资源来维护长连接 |
支持服务器主动向客户端推送数据 | 可能会增加服务器端的复杂性 |
可以减少 HTTP 请求头和响应头的大小,降低网络延迟和流量 | 需要保证 WebSocket 连接的稳定性和可靠性 |
WebSocket报文格式相对简单,由帧(Frame)组成。
基本的WebSocket帧结构包括:FIN
、RSV
、Opcode
、Mask
、Payload Length
、Masking Key
和Payload Data
等字段。
WebSocket 握手过程是客户端和服务器之间建立 WebSocket 连接的过程,它遵循 HTTP 协议的规范。
下面是 WebSocket 握手的基本步骤:
Upgrade: websocket
、Connection: Upgrade
、Sec-WebSocket-Key
等。其中,Sec-WebSocket-Key
是一个随机的 Base64 编码的字符串,用于确保服务器能够识别客户端的 WebSocket 请求。101 Switching Protocols
,表示协议切换。Upgrade: websocket
、Connection: Upgrade
、Sec-WebSocket-Accept
等。其中,Sec-WebSocket-Accept
是通过将客户端请求头中的 Sec-WebSocket-Key
加上一个特定的 GUID(全局唯一标识符),然后计算 SHA-1 摘要后进行 Base64 编码得到的。绝大多数主流的编程语言都有支持 WebSocket 的库或框架,使得开发者可以方便地在其应用程序中实现 WebSocket 功能。以下是一些常见编程语言及其对应的 WebSocket 库:
ws
、socket.io
websockets
、socket.io-client
javax.websocket
、Java-WebSocket
WebSocketSharp
、SignalR
gorilla/websocket
、nhooyr/websocket
websocket-ruby
、faye-websocket
ratchet/pawl
、cboden/Ratchet
WebSocket 本身并没有提供通信的安全性,但可以通过其他机制来增强通信的安全性,例如使用 TLS/SSL 加密连接。
以下是保证 WebSocket 通信安全性的一些方法:
wss://
协议来指定安全的 WebSocket 连接。以下是一些常用的Python WebSocket库:
库名称 | 说明 |
---|---|
websockets | 1. 提供了简单而强大的API,易于使用 。 2. 支持 异步 操作,适用于高性能的WebSocket应用程序。3. 可以同时作为 客户端 和服务器 端使用。 4. 具有良好的文档和活跃的社区支持。 |
autobahn-python | 1. 功能丰富 ,提供了完整的WebSocket协议实现。 2. 支持 高级特性 ,如消息压缩、WebSocket扩展等。 3. 提供了WebSocket 客户端 和服务器 端的实现。 4. 与Twisted框架紧密集成,支持 异步 操作。 5. 适用于复杂的WebSocket应用场景,如实时游戏、聊天应用等。 |
socket.io-client-python | 1. 是Python版本的Socket.IO客户端库,兼容JavaScript版Socket.IO 。 2. 提供了与JavaScript版Socket.IO类似的API, 易于使用 。 3. 支持WebSocket传输和轮询传输两种方式。 4. 适用于与使用Socket.IO实现的WebSocket服务器进行通信。 |
Tornado | 1. 是一个强大的异步Web框架 ,支持WebSocket通信。 2. 提供了WebSocket 客户端 和服务器 端的实现。 3. 集成了WebSocket路由和处理器,方便WebSocket应用程序的开发。 4. 适用于需要高性能异步通信的应用场景,如实时数据传输、即时通讯等。 |
django-websocket-redis | 1. 基于Django框架,使用Redis作为消息队列,用于实现WebSocket通信。 2. 可以轻松地集成到Django应用程序中。 3. 提供了简单而有效的API来处理WebSocket连接。 4. 适用于需要在Django应用程序中实现WebSocket通信的场景。 |
aiowebsocket | 1. 是一个基于异步IO的WebSocket库,专门用于Python的asyncio框架。 2. 提供了异步的WebSocket客户端和服务器端实现。 3. 适用于需要在asyncio框架下进行高性能异步通信的应用场景。 |
Flask-SocketIO | 1. 支持房间管理功能,可以将客户端分组到不同的房间中,并在房间内进行广播或单播消息。 2. 具有跨浏览器兼容性,能够在各种主流浏览器中稳定运行。 3. 集成简单,易于安装和使用,且有良好的文档和社区支持。 |
详细用法请查阅:
使用websockets模块实现一个简单的聊天室案例:用户通过浏览器进入聊天室,多个用户可实时聊天。前端采用Javascript+html
。前端代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>WebSocket 聊天室</title> <style> body { margin: 0; padding: 0; font-family: Arial, sans-serif; } .container { width: 80%; margin: 0 auto; text-align: center; padding-top: 20px; } .chat-container { display: flex; flex-direction: column; border: 1px solid #ccc; border-radius: 5px; overflow: hidden; margin-top: 20px; height: 400px; /* 设置容器的固定高度 */ } .message-container { flex-grow: 1; overflow-y: auto; padding: 10px; } .message { margin-bottom: 10px; max-width: 100%; /* 让消息div宽度占满容器 */ } .message.received { text-align: left; background-color: #f0f0f0; border-radius: 5px; padding: 5px 10px; } .message.sent { text-align: right; background-color: #e2f3f5; border-radius: 5px; padding: 5px 10px; } #message { width: 100%; height: 40px; margin-top: 20px; border: 1px solid #ccc; border-radius: 5px; padding: 0 10px; box-sizing: border-box; } </style> </head> <body> <div class="container"> <h1>WebSocket 聊天室</h1> <div class="chat-container"> <div class="message-container" id="messages"></div> <input type="text" id="message" placeholder="输入消息并按 Enter 发送"> </div> </div> <script> var socket = new WebSocket("ws://localhost:8765"); socket.onopen = function(event) { console.log("WebSocket 连接已建立"); }; socket.onmessage = function(event) { var messageDiv = document.createElement("div"); messageDiv.textContent = event.data; messageDiv.className = "message received"; document.getElementById("messages").appendChild(messageDiv); scrollToBottom(); }; document.getElementById("message").addEventListener("keypress", function(event) { if (event.key === "Enter") { var message = this.value; var messageDiv = document.createElement("div"); messageDiv.textContent = message; messageDiv.className = "message sent"; document.getElementById("messages").appendChild(messageDiv); scrollToBottom(); socket.send(message); this.value = ""; } }); function scrollToBottom() { var messageContainer = document.getElementById("messages"); messageContainer.scrollTop = messageContainer.scrollHeight; } </script> </body> </html>
后端代码如下:
import asyncio import websockets from datetime import datetime # 客户端列表,用于存储所有连接到服务器的客户端 clients = set() # 处理新连接的函数 async def handle_client(websocket, path): # 添加新连接的客户端到客户端列表 clients.add(websocket) try: # 获取当前时间,格式化时分秒 now = datetime.now() time_format = now.strftime("%H:%M:%S") # 发送欢迎消息给新连接的客户端 client_addr = websocket.remote_address print(f"{time_format} Client {client_addr} connected!") welcome_message = "已连接服务器" await websocket.send(welcome_message) # 循环处理客户端发送的消息 async for message in websocket: # 将收到的消息发送给所有连接到服务器的客户端 for client in clients: # 获取当前时间,格式化时分秒 now = datetime.now() time_format = now.strftime("%H:%M:%S") print(f"{time_format} Received Client {client.remote_address} message: {message}") # 打印收到的消息 await client.send(message) finally: # 当连接关闭时,从客户端列表中移除对应的客户端 client_addr = websocket.remote_address print(f"Client {client_addr} disconnected!") clients.remove(websocket) # 启动 WebSocket 服务器 start_server = websockets.serve(handle_client, "localhost", 8765) # 启动事件循环,等待连接 asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()
启动WebSocket服务后,启用http服务,然后浏览器即可连接websocket进入聊天室进行群聊:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。