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

news2025/3/18 1:06:27

概述

  • 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.coloradmin.cn/o/2316897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC (二)请求处理

目录 章节简介 一 请求处理&#xff08;初级&#xff09; eg:请求头 二 请求处理&#xff08;进阶&#xff09; eg:请求体 三 获取请求头 四 获取Cookie 五 级联封装 六 使用RequestBoby封装JSON对象 七 文件的上传 八 获取整个请求 HttpEntity 九 原生请求 Spring…

1.6、Java继承、构造方法、数组

子类可以增加字段、增加方法或覆盖父类方法&#xff0c;但继承不会删除任何字段和方法不恰当认为super 同 this 引用是类似的概念&#xff0c;其实super不是一个对象的引用&#xff0c;不能将值super赋给另一个对象变量&#xff0c;super只是一个指示 编译器调用父类方法的特殊…

通义万相 2.1 与蓝耘智算平台的深度协同,挖掘 AIGC 无限潜力并释放巨大未来价值

我的个人主页 我的专栏&#xff1a; 人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01; 点赞&#x1f44d;收藏❤ 引言&#xff1a;AIGC 浪潮下的新机遇 在当今数字化飞速发展的时代&#xff0c;人工智能生成内容&…

专题|Python贝叶斯金融数据应用实例合集:随机波动率SV模型、逻辑回归、参数更新、绩效比较BEST分析亚马逊股票、普尔指数...

原文链接&#xff1a;https://tecdat.cn/?p41020 本专题合集系统梳理了贝叶斯方法在金融数据分析与分类建模中的前沿应用。合集聚焦于PyMC3概率编程框架&#xff0c;深度探讨了共轭先验参数更新、贝叶斯逻辑回归、贝叶斯夏普比率等核心算法在实际场景中的落地实践&#xff08;…

Linux调度器 --- 负载均衡的存在的问题

文章目录 前言一、简介二、Linux 调度器2.1 在单核系统上&#xff0c;CFS 非常简单2.2 在多核系统上&#xff0c;CFS 变得非常复杂2.2.1 负载均衡算法2.2.2 优化措施 三、Linux调度器负载均衡的存在的问题3.1 组负载不均衡问题&#xff08;Group Imbalance Bug&#xff09;3.2 …

从零开始用AI开发游戏(三)背景故事

《迷域回响》背景故事 第一章&#xff1a;失落的符文纪元 在远古的“艾瑟兰”大陆&#xff0c;掌握空间魔法的「筑界者文明」曾建造了连通万界的回响迷宫——这座迷宫既是试炼场&#xff0c;也是囚笼。文明巅峰时期&#xff0c;筑界者将禁忌知识刻入虚空符文&#xff0c;嵌于…

IXTUR气控永磁铁:以高精度气控和稳定磁场,为机器人应用提供稳定抓取力

在现代工业生产和物流领域&#xff0c;物料的抓取与搬运是影响生产效率和成本控制的重要环节。传统夹爪在面对不同材质、形状和重量的物体时&#xff0c;常常存在适应性差、抓取不稳定、操作复杂等问题&#xff0c;导致生产流程中频繁出现停机调整&#xff0c;增加了人工干预成…

硬件驱动——51单片机:寄存器、LED、动态数码管

目录 一、51单片机 1.寄存器 二、LED点灯 1.原理 2.封装函数 3.顺序点灯 4.特定位点灯 三、动态数码管 1.原理 2.封装函数 3.0~9跳变 4.顺序移位0~9跳变 一、51单片机 1.寄存器 51单片机共40个引脚&#xff0c;其中P0,P1,P2,P3是四个有8引脚的寄存器&#xff0…

2025 香港 Web3 嘉年华:全球 Web3 生态的年度盛会

自 2023 年首届香港 Web3 嘉年华成功举办以来&#xff0c;这一盛会已成为全球 Web3 领域规模最大、影响力最深远的行业活动之一。2025 年 4 月 6 日至 9 日&#xff0c;第三届香港 Web3 嘉年华将在香港盛大举行。本届活动由万向区块链实验室与 HashKey Group 联合主办、W3ME 承…

【MySQL】多表查询(笛卡尔积现象,联合查询、内连接、左外连接、右外连接、子查询)-通过练习快速掌握法

在DQL的基础查询中&#xff0c;我们已经学过了多表查询的一种&#xff1a;联合查询&#xff08;union&#xff09;。本文我们将系统的讲解多表查询。 笛卡尔积现象 首先&#xff0c;我们想要查询emp表和stu表两个表&#xff0c;按照我们之前的知识栈&#xff0c;我们直接使用…

Leetcode-132.Palindrome Partitioning II [C++][Java]

目录 一、题目描述 二、解题思路 【C】 【Java】 Leetcode-132.Palindrome Partitioning IIhttps://leetcode.com/problems/palindrome-partitioning-ii/description/132. 分割回文串 II - 力扣&#xff08;LeetCode&#xff09;132. 分割回文串 II - 给你一个字符串 s&…

在 macOS 上优化 Vim 用于开发

简介 这篇指南将带你通过一系列步骤&#xff0c;如何在 macOS 上优化 Vim&#xff0c;使其具备 代码补全、语法高亮、代码格式化、代码片段管理、目录树等功能。此外&#xff0c;我们还会解决在安装过程中可能遇到的常见错误。 1. 安装必备工具 在开始 Vim 配置之前&#xff…

SOME/IP-SD -- 协议英文原文讲解8

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.4.4 S…

【Agent实战】货物上架位置推荐助手(RAG方式+结构化prompt(CoT)+API工具结合ChatGPT4o能力Agent项目实践)

本文原创作者:姚瑞南 AI-agent 大模型运营专家,先后任职于美团、猎聘等中大厂AI训练专家和智能运营专家岗;多年人工智能行业智能产品运营及大模型落地经验,拥有AI外呼方向国家专利与PMP项目管理证书。(转载需经授权) 目录 结论 效果图示 1.prompt 2. API工具封…

PyTorch 深度学习实战(11):强化学习与深度 Q 网络(DQN)

在之前的文章中&#xff0c;我们介绍了神经网络、卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;、Transformer 等多种深度学习模型&#xff0c;并应用于图像分类、文本分类、时间序列预测等任务。本文将介绍强化学习的基本概念&#xff0…

Python学习第十九天

Django-分页 后端分页 Django提供了Paginator类来实现后端分页。Paginator类可以将一个查询集&#xff08;QuerySet&#xff09;分成多个页面&#xff0c;每个页面包含指定数量的对象。 from django.shortcuts import render, redirect, get_object_or_404 from .models impo…

Windows环境下安装部署dzzoffice+onlyoffice的私有网盘和在线协同系统

安装前需要准备好Docker Desktop环境&#xff0c;可查看我的另一份亲测安装文章 https://blog.csdn.net/qq_43003203/article/details/146283915?spm1001.2014.3001.5501 1、安装配置onlyoffice 1、Docker 拉取onlyoffice容器镜像 管理员身份运行Windows PowerShell&#x…

ChatPromptTemplate的使用

ChatPromptTemplate 是 LangChain 中专门用于管理多角色对话结构的提示词模板工具。它的核心价值在于&#xff0c;开发者可以预先定义不同类型的对话角色消息&#xff08;如系统指令、用户提问、AI历史回复&#xff09;&#xff0c;并通过数据绑定动态生成完整对话上下文。 1.…

Blender插件NodeWrangler导入贴图报错解决方法

Blender用NodeWrangler插件 CtrlShiftT 导入贴图 直接报错 解决方法: 用CtrlshiftT打开需要导入的材质文件夹时&#xff0c;右边有一个默认勾选的相对路径&#xff0c;取消勾选就可以了。 开启node wrangler插件&#xff0c;然后在导入贴图是取消勾选"相对路径"&am…

java项目之基于ssm的药店药品信息管理系统(源码+文档)

项目简介 药店药品信息管理系统实现了以下功能&#xff1a; 个人信息管理 负责管理个人用户的信息。 员工管理 负责管理药店或药品管理机构的员工信息。 药品管理 负责管理药品的详细信息&#xff0c;可能包括药品名称、成分、剂量、价格、库存等。 进货管理 负责管理药品…