当前位置: 首页 > news >正文

websocket学习手册及python实现简单的聊天室

概述

  • WebSocket 是一种网络通信协议,允许在单个 TCP 连接上进行全双工通信。它最核心的优势就在于实现了持久连接,实现了实时的数据传输。
  • HTTP 协议有一个很大的缺点,通信只能由客户端发起,服务器返回响应后连接就会关闭,如果我们想要知道任务连续的状态变化的话,就需要通过轮询来获取状态,这种方法的效率就会非常低。
  • WebSocket需要维护连接,这需要额外的开销,包括内存和CPU,没有必要需求无需使用
  • WebSocket协议是一种可靠的、高效的、双向的、持久的通信协议,支持文本和二进制数据。

如何建立连接

+---------+                         +---------+
| Client  |                         | Server  |
+---------+                         +---------+
     |                                   |
     | 1. HTTP GET (Upgrade request)     |
     |---------------------------------->|
     |                                   |
     | 2. HTTP 101 Switching Protocols   |
     |<----------------------------------|
     |                                   |
     | 3. WebSocket Connection Established |
     |<---------------------------------->|
     |                                   |

WebSocket 连接的建立过程基于 HTTP 协议,我使用postman建立一个连接,打开握手详情,可以看到这些信息:

在这里插入图片描述
在这里插入图片描述

  1. 首先,客户端发送一个 HTTP GET 请求,包含以下关键头信息:

    • Upgrade: websocket:表示希望升级到 WebSocket 协议。

    • Connection: Upgrade:表示要求升级连接。

    • Sec-WebSocket-Key:一个随机生成的 Base64 编码字符串,用于验证服务器。

    • Sec-WebSocket-Version:指定 WebSocket 协议版本(通常为 13)。

  2. 服务器检查请求头,如果支持 WebSocket,返回 HTTP 101 状态码(Switching Protocols),并包含以下头信息:

    • Upgrade: websocket:确认升级到 WebSocket 协议。
    • Connection: Upgrade:确认连接升级。
    • Sec-WebSocket-Accept:基于客户端的 Sec-WebSocket-Key 计算的值,用于验证。

关于wss和ws

wswss 是 WebSocket 协议的两种不同形式,主要区别在于 安全性数据传输方式

wswss
特性非加密加密
协议普通 TCP基于 TLS/SSL 的 TCP
安全性数据明文传输,不安全数据加密传输,安全
适用场景内部网络、开发环境生产环境、敏感数据传输
默认端口80443
URL 前缀ws://wss://

简单实现

from fastapi import FastAPI, APIRouter, WebSocket, WebSocketDisconnect

app = FastAPI()
router = APIRouter(prefix='/demo', tags=['demo'])

# WebSocket 端点
@router.websocket("/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str):
    # 接受客户端连接
    await websocket.accept()
    while True:
        try:
            # 接收客户端发送的消息
            data = await websocket.receive_text()
            # 打印接收到的消息
            print(f"Received message: {data}")
            # 将消息原样发送回客户端
            await websocket.send_text(f"Echo: {data}")
        except Exception as e:
            print(f"Error: {e}")
            break

app.include_router(router)

实战-实现一个聊天室

import json

from fastapi import FastAPI, APIRouter, WebSocket, WebSocketDisconnect

app = FastAPI()
router = APIRouter(prefix='/demo', tags=['demo'])


class ConnectionManager:
    def __init__(self):
        self.active_connections: dict[str, WebSocket] = {}

    async def connect(self, websocket: WebSocket, user_id: str):
        await websocket.accept()
        self.active_connections[user_id] = websocket

    def disconnect(self, user_id: str):
        if user_id in self.active_connections:
            del self.active_connections[user_id]

    async def send_message(self, message: str, user_id: str, target_user: str):
        # 向目标用户发送消息
        if websocket := self.active_connections.get(target_user):
            data = json.dumps({"message": message, "from_user": user_id})
            await websocket.send_text(data)


manager = ConnectionManager()


# WebSocket 端点
@router.websocket("/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str):
    await manager.connect(websocket, user_id)
    try:
        while True:
            data = await websocket.receive_text()
            data = json.loads(data)
            # 接收到消息后,向目标用户发送消息
            await manager.send_message(data.get("message"), user_id, data.get("target_user"))
    except WebSocketDisconnect:
        manager.disconnect(user_id)
        print(f"用户 {user_id} 断开连接")


app.include_router(router)

这里使用了user_id作为标志,根据用户id向指定的对象发送消息,可以看到8888用户给6666用户发送了个hello,而6666用户也接收到了相应的消息
在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/66370.html

相关文章:

  • 卡特兰数专题
  • KCD 北京站丨Volcano 邀您畅聊云原生智能调度技术与应用
  • 卷积神经网络(CNN):深度解析其原理与特性
  • hive-进阶版-1
  • 正常的一个编码器的架构是怎么样,有哪些模块构成
  • 蓝桥杯刷题 Day1 高精度加法
  • 基于SpringBoot + Vue 的校园论坛系统
  • 记第一次跟踪seatunnel的任务运行过程四——getJobConfigParser().parse()的动作
  • java每日精进 3.12 【WebSocket进阶】
  • LabVIEW正弦信号三参数最小二乘拟合
  • sensor数据在整个rk平台的框架流程是怎么样,
  • Maven 构建 项目测试
  • 前端PayPal支付按钮集成(Vue3)
  • AI + 游戏开发:如何用 DeepSeek 打造高性能开心消消乐游戏
  • React篇之three渲染
  • MB90540/540G/545/545G Series
  • 锤头线和倒锤头线
  • OpenHarmony 5.0 拨号键盘自定义暗码启动其他应用
  • Linux常见问题与分析
  • OBJ文件生成PCD文件(python 实现)
  • MTK Android12 安装app添加密码锁限制
  • Android Framwork 之深入理解 IPC Binder机制
  • vue2安装scss
  • C语言实现十六进制转十进制
  • 谷歌 DeepMind 重磅出击,多款 AI 模型震撼登场
  • 【A2DP】蓝牙音频编解码器互操作性要求详解
  • keepalived系列-自启动配置无效
  • Celery - 入门(get-started)
  • DeepSeek选择方向的优势
  • 阿里巴巴发布 R1-Omni:首个基于 RLVR 的全模态大语言模型,用于情感识别