最近一直在写 python 方面的东西,一直都在 websocket 通讯上卡住;
我很想知道 python 有没有好像 php 的 workerman 的库,可以直接使用 websocket,然后写业务逻辑就好了;
我现在是 flask + flask_socketio,可是碰到很尴尬的事情,发现 SocketIO 在前端好像是轮询方式一样,不停的在请求;
其实我只是想要一个长连接而已;
其次是发现我用 flask + flask_socketio 构架,web 也是他,socket 也是他,到底我怎么在 web 的后端业务逻辑里面去使用 socket 给用户主动推送消息呢?比如 php 的 websocket 里 GatewayClient 一样,只要直接调用就可以后端给前端发消息了;
这简直是我最大的挣扎点,各位前辈请轻拍,各种文档资料 github 案例都给我吧,我不怕麻烦,不嫌弃案例多;
只要能帮助到,我愿意一个个的看,一个个的深究; 感谢。。。。。
from App import app # 从app模块中导入app应用
from flask_socketio import SocketIO
from threading import Lock, Thread
async_mode = None
socketio = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()
# 后台线程 产生数据,即刻推送至前端
def background_thread():
count = 0
while True:
socketio.sleep(2)
count += 1
socketio.emit('server_response', {'data': 'Hello', 'count': count}, namespace='/test') # 注意:这里不需要客户端连接的上下文,默认 broadcast = True !!!!!!!
# 与前端建立 socket 连接后,启动后台线程
@socketio.on('connect', namespace='/test')
def test_connect():
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(target=background_thread)
#防止被引用后执行,只有在当前模块中才可以使用
if __name__ == '__main__':
# app.debug = True # 设置调试模式,生产模式的时候要关掉debug
# app.run() # 启动服务器
socketio.run(app, debug=True)
这是我的flask,比如我在别的路由的事件方法里面,写一个主动发送socket给前端,我都不知道咋写。这大概是python不太懂的尴尬地方。线程真的是python的命啊。 其实我只是想,在某个路由事件里面,当那个URL被访问,就触发一个socket给前端。让前端知道,喔,有数据进入了,大概这个意思;
1
PulpFunction 2019-01-30 06:49:52 +08:00 via Android
李辉大佬肯定会 这么早就写代码了???
|
2
est 2019-01-30 08:10:04 +08:00 via Android
py 有 gunicorn worker,php 有 fpmworker
都是多进程在服务器跑。那么问题来了,你如何判断客户长连接连上哪个进程的? 我好奇 woekeeman 如何解决这个问题的? |
3
Trim21 2019-01-30 08:10:37 +08:00 via iPhone
用过 aiohttp 里面的 socketio,应该是差不多的用法吧(
在 flask 的路由函数里跟 background thread 函数里面一样,直接 emit 出去不可以吗? |
4
ratazzi 2019-01-30 08:19:44 +08:00 via iPhone
socketio 支持几种模式,轮询是其中一种,要看是什么原因导致没用 websocket
|
5
rogwan 2019-01-30 08:28:31 +08:00 via Android
@smallgoogle
直接用 Flask-Sockets 就可以,前端基本上都直接支持 websocket 了 cc @est 没法知道是哪个进程连上的吧,还有多终端连接的问题,这个要实现,要么要加上用户系统来判断,新建一个 ws 断开老的 ws,否则很难准确判断。 |
6
vZexc0m 2019-01-30 16:33:38 +08:00
以前用 tornado 写过相关的代码,具体识别用户连接的方法是客户端建立 websocket 连接的时候在 URL 上带上登录凭证,然后服务端将用户和 websocket 连接对应起来,如果要向某个用户主动推送消息,只需要找到用户的 websocket 连接进行发送消息即可。
|
7
smallgoogle OP @est workerman 有一个唯一客户端 ID 作为标识。
|
8
est 2019-01-31 08:06:01 +08:00 via Android
@smallgoogle 所以其实楼主代码里没看到相关逻辑。
|
9
769932247 2019-02-13 14:12:02 +08:00
楼主还在做么,我最近也在写,遇到一些问题
|
10
lsls931011 2019-02-14 17:40:34 +08:00
像我们 php 程序员是使用 swoole 的,哈哈
|
11
lakechan96 2019-02-17 16:56:47 +08:00
@smallgoogle SocketIO 有 sid 做唯一 ID
当发送到名称为 sid 的 room 时等同于发送给指定用户 但是在 @socketio.* 的 context 之外,你需要自己自己维护 sid 来调用 emit 发送,在 context 之内可以直接使用 request.sid |
12
smallgoogle OP @769932247 什么问题?
|
13
shange123 2019-02-19 10:52:36 +08:00
使用 tornado 啊,自带 websocket
|