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

FastAPI 学习之路(五十)WebSockets(六)聊天室完善

我们这次只是对于之前的功能做下优化,顺便利用下之前的操作数据的接口,使用下数据库的练习。

在聊天里会有一个上线的概念。上线要通知大家,下线也要通知大家谁离开了,基于此功能我们完善下代码。

首先,我们的登录用户还是用了之前分享中的数据库相关用户,直接调用,之前也是从数据库获取用户,校验密码,密码成功后才让登录。这个在FastApi学习之路(四十七)WebSockets(三)登录后才可以聊天中就已经提到过了。

其次,我们建立了链接管理类,但是我们现在的链接都是没有针对发消息做管理的,我们去扩展下我们之前的发消息的类。

"""
websocket 链接管理
"""from typing import List, Dictfrom starlette.websockets import WebSocketclass ConnectionManager:def __init__(self):"""存放链接"""self.active_connections: List[Dict[str, WebSocket]] = []async def connect(self, user: str, ws: WebSocket):"""链接"""await ws.accept()self.active_connections.append({"user": user, "ws": ws})async def disconnect(self, user: str, ws: WebSocket):"""断开链接,移除"""self.active_connections.remove({"user": user, "ws": ws})@staticmethodasync def send_personal_message(message: str, ws: WebSocket):"""发送所有人消息"""await ws.send_text(message)async def send_other_message(self, message: dict, user: str):"""发送个人消息"""for coon in self.active_connections:if coon["user"] == user:await coon["ws"].send_json(message)async def broadcast(self, data: str):"""广播"""for conn in self.active_connections:await conn["ws"].send_text(data)

       增加了广播消息,和增加了发所有消息和针对个人发消息。我们现在实现的是针对所有人和广播。那么我们看下,我们的管理聊天链接的已经完善。

       接下来我们就是去实现如何接受消息。

@app.websocket("/items/ws/{user}")
async def websocket_chat_method(websocket: WebSocket,user: str,cookie_or_token: str = Depends(get_cookie_or_token)
):await ws_manager.connect(user, websocket)await ws_manager.broadcast(user + "进入聊天室")try:while True:data = await websocket.receive_text()await ws_manager.send_personal_message(f"你说:{data}", websocket)await ws_manager.broadcast(f"用户{user}说:{data}")except WebSocketDisconnect as e:await ws_manager.disconnect(user, websocket)await ws_manager.broadcast(f"用户{user}离开")

其实很简单,当你登录的时候,就广播一下,某某进入了聊天室,然后就是等消息,那么我们看下前端需要如何改造:

<!DOCTYPE html>
<html>
<head><title>Chat</title>
</head>
<body>
<h1>WebSocket 聊天</h1>
<form action="" onsubmit="sendMessage(event)"><input type="text" id="messageText" autocomplete="off"/><button>Send</button>
</form>
<button onclick="logout()">退出</button>
<ul id='messages'>
</ul>
<script>var  token=window.localStorage.getItem("token")if (token==null ){window.location.href="/login"}var ws = new WebSocket("ws://localhost:8000/items/ws/"+token+"?token="+token);ws.onmessage = function (event) {var messages = document.getElementById('messages')var message = document.createElement('li')var content = document.createTextNode(event.data)message.appendChild(content)messages.appendChild(message)};function sendMessage(event) {var input = document.getElementById("messageText")ws.send(input.value)input.value = ''event.preventDefault()}function logout() {window.localStorage.removeItem("token")window.location.href='/login'}
</script></body></html>

其实就是在登录的时候增加了对应人的链接,接下来看下效果:

登录A:

首先,第一个用户已经登录进来了,接下来登录第用户B

登录B:

看下用户A能否接收到用户B的上线消息:

如上图,我们可以看到,当用户B登录后,用户A也收到了B上线的消息,我们试着发送消息:

用户A发送消息

用户B收到消息:

用户B发送消息:

用户A收到消息:

当用户离开时:

这样聊天室就相对完善了。我们从简单的聊天室入手,慢慢改造我们的代码,慢慢完善 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 近源渗透简介
  • 5. 基于Embedding实现超越elasticsearch高级搜索
  • python数据可视化(6)——绘制散点图
  • 【人工智能】Transformers之Pipeline(一):音频分类(audio-classification)
  • huggingface 数据集和模型加速下载, hfdata 输出为json
  • 实验二:图像灰度修正
  • 【vue深入学习第1章】Vue.js 中的 Ajax 处理:vue-resource 库的深度解析
  • 聊聊自动驾驶中的路径和轨迹
  • 算法力扣刷题记录 四十八【513.找树左下角的值】
  • Oralce笔记-解决Oracle18c中ORA-28001: 口令已经失效
  • 【持续集成_05课_Linux部署SonarQube及结合开发项目部署】
  • CSS3实现彩色变形爱心动画【附源码】
  • Linux命令更新-sort 和 uniq 命令
  • 【车载测试收徒】【UDS诊断中的协议:ISO-14229中文】
  • bash: ip: command not found
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • flutter的key在widget list的作用以及必要性
  • laravel 用artisan创建自己的模板
  • orm2 中文文档 3.1 模型属性
  • PAT A1050
  • SpingCloudBus整合RabbitMQ
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 规范化安全开发 KOA 手脚架
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 使用parted解决大于2T的磁盘分区
  • 通信类
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • linux 淘宝开源监控工具tsar
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​​​【收录 Hello 算法】9.4 小结
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (31)对象的克隆
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (pojstep1.1.2)2654(直叙式模拟)
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (四)Android布局类型(线性布局LinearLayout)
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (新)网络工程师考点串讲与真题详解
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)scrum常见工具列表
  • (转)详解PHP处理密码的几种方式
  • .DFS.
  • .Net 基于.Net8开发的一个Asp.Net Core Webapi小型易用框架
  • .NET 使用配置文件
  • .net 微服务 服务保护 自动重试 Polly
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET/C#⾯试题汇总系列:集合、异常、泛型、LINQ、委托、EF!(完整版)
  • .Net程序帮助文档制作
  • .Net组件程序设计之线程、并发管理(一)
  • [Android]使用Retrofit进行网络请求
  • [C#] 如何调用Python脚本程序