Python中如何实现WebSocket实时弹幕或即时聊天系统?

现在想用 gevent-websocket 或者 tornado 做,请问有相关的例子或教程吗?或者提供一下后端设计思路。
Python中如何实现WebSocket实时弹幕或即时聊天系统?

25 回复

我有个项目,用 Python 抓过 websocket 的数据


用Python搞WebSocket实时系统,核心就靠websocketsasyncioaiohttp。下面给你个最简版的聊天室示例,跑起来就能看到效果:

import asyncio
import websockets
import json

# 存所有连接的客户端
connected_clients = set()

async def handle_connection(websocket, path):
    # 新连接加入集合
    connected_clients.add(websocket)
    try:
        async for message in websocket:
            # 收到消息就广播给所有客户端
            data = json.loads(message)
            broadcast_msg = json.dumps({
                'user': data.get('user', 'Anonymous'),
                'text': data['text']
            })
            await asyncio.gather(*[
                client.send(broadcast_msg)
                for client in connected_clients
                if client != websocket  # 可选:不发给发送者自己
            ])
    finally:
        # 连接断开时移除
        connected_clients.remove(websocket)

async def main():
    server = await websockets.serve(handle_connection, "localhost", 8765)
    print("WebSocket服务器已启动 ws://localhost:8765")
    await server.wait_closed()

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

前端配合的HTML(存为client.html):

<!DOCTYPE html>
<body>
<input id="msg" placeholder="输入消息"><button onclick="send()">发送</button>
<div id="chat"></div>
<script>
const ws = new WebSocket('ws://localhost:8765');
ws.onmessage = e => {
    const data = JSON.parse(e.data);
    document.getElementById('chat').innerHTML += 
        `<div><b>${data.user}:</b> ${data.text}</div>`;
};
function send() {
    const msg = document.getElementById('msg').value;
    ws.send(JSON.stringify({user: '用户', text: msg}));
}
</script>
</body>

跑起来:先装pip install websockets,运行Python脚本,然后用浏览器开多个client.html页面就能互发消息了。实际用的话得加用户认证、消息持久化这些,但骨架就这几十行代码。

简单说就是:一个服务器维护连接池,收到消息就遍历发送。

tornado 自带 websocket 特别简单,以前用 websocket 做过一个实时日志

直接用 socket.io 会简单很多

简单聊天系统的架构: 起一个 Web 服务、一个 WebSocket 服务、一个 database

基本上是用 database 做服务间的数据共享,我是用 Redis

用户透过 Web 服务做验证、取得大厅或房间数据

从大厅进入房间后,渲染 WebSocket 的客端 JS 代码,带用户 Token 联接 WebSocket 服务

抄 openstack 的 vnc 服务

flask + socketio 是怎么部署的,uwsgi 对 socketio 不友好。。好像只能用 gevent

Flask-SocketIO 不错

弹幕系统类似全站广播 用 rabbitmq stomp+ sockjs 做很容易的

tornado 或 aiohttp:原生 ws
sockjs + tornado:比较稳的方案
flask:在 tornado 或 gevent 上跑 flask

一个老早前写的例子:
https://github.com/fy0/chat

我是万年 tornado 用户,现在在考虑转 aiohttp。

就用 gevent-websocket 起了服务之后在 rerequest 里面取 wsgi.websocket 就好啦

挺早之前写的,忘了是用的哪个容器了.f lask 插件就哪个f lask-socketio

多少用户同时在线??

这个怎么取得用户信息和监控 websocket 的连接与关闭

我想知道是怎么做的数据共享,还有 socket 怎么带 token。

  1. 两个服务共用一个数据库
    2. send()的时候带上 token 即可

感谢回复。我想的是用户通过一个短连接发送消息存入数据库,然后这个长连接能够实时获取用户发送的消息,然后发送给客户端。请问有什么好的实现方式吗


“送消息存入数据库”、“服务推送到各客户端” 都是通过 WebSocket 的连接

客端来看,分别对应到 send()跟 onmessage()

服务端来看,当客端 send()消息来时,存入数据库,并且对每个连接的客端推送消息的内容

流程整体会是
1. 建立 WebSocket 连接
2. 客端透过 WebSocket 的 send()方法发送消息到服务端
3. 服务端将消息存入数据库后,推送消息到各个客端
4. 客端触发 onmessage 的回调,将推送内容显示

感谢!如果我需要实现两个人的即使通讯,有什么好的思路吗.

django + channels

楼主开始动手了吗?打算开源吗?想一起参与

正在写 用的 tornado.websocket,开源的话 感觉代码太烂,拿不出手

。。。过分》。。我微博被强制销户了…土狗怎么登录=。=

线上服务,流量大的话还是慎用吧,七牛欢迎你

回到顶部