自学 websocket(六):实战上手 websockets 的广播机制

websockets 的广播机制

  • 老规矩,先上代码再解析
  • 这篇主要是学习websockets广播功能
  • 可以同时将一个消息发送给多个客户端,保证多个客户端能实时接收到同样的信息
  • 只会python不会写html和js也没有关系,代码很简洁,重点是理解websockets的广播功能并用python写广播服务器
server端
import asyncio
import datetime
import random

import websockets

Connections = set()


# 广播写在这个函数里面
async def broadcast_time():
    while True:
        message = datetime.datetime.utcnow().isoformat() + "Z"
        websockets.broadcast(Connections, message)
        await asyncio.sleep(random.random() * 2 + 1)  # 生成一个在1到3之间的随机浮点数


# 服务处理函数,仅处理 client 的添加和删除
async def register(websocket):
    Connections.add(websocket)
    try:
        # 使用try保证,无论发生了什么情况,都会关闭掉连接
        await websocket.wait_closed()
    finally:
        # 确保在websocket关闭时从Connections集合中删除它
        Connections.remove(websocket)


async def main():
    async with websockets.serve(register, "localhost", 5678):
        print(f"[server on 5678]")
        await broadcast_time()


if __name__ == '__main__':
    asyncio.run(main())

html 网页
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websocket demo</title>
</head>
<body>
    <script src="show_time.js"></script>
</body>
</html>
js 代码
// 当网页加载完成后执行以下代码
window.addEventListener("DOMContentLoaded", () => {
    // 创建一个空的无序列表(ul)并将其添加到文档的 body 元素中
    const messages = document.createElement("ul");
    document.body.appendChild(messages);

    // 创建一个 WebSocket 对象并将其连接到本地主机上的端口 5678
    const websocket = new WebSocket("ws://localhost:5678/");

    // 当 WebSocket 接收到消息时,将消息添加到无序列表中作为列表项(li)
    websocket.onmessage = ({data}) => {
        const message = document.createElement("li");
        const content = document.createTextNode(data);
        message.appendChild(content);
        messages.appendChild(message);
    };
});
关键点提示:
  • server 端
  1. 启动一份server服务器的代码都是一样的,copy即可
  2. 在这个server中,服务处理函数register只有一个作用,就是负责新client 的添加 和离开client的删除
  3. Connections = set()就是所有在线client的用户集合,广播时的参数就是这个集合
  4. register中,使用try…finally的目的:确保无论任何情况下client的websocket关闭,都要从Connections集合中删除它
  5. 此处没有使用await asyncio.Future(),而是换成了await broadcast_time()协程,这个协程需要在server打开时进行,所以放在了服务器利用with保持开启的期间,并且while True保证了广播时间功能可以永远运行下去,而不需要asyncio.Future(),就算把这一行代码下载后面程序也不会运行到它那里去
  • 实现效果
    • 因为浏览器的打开时间不同,所以只需关注最后三条消息,可以看见他们是一样的

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值