最近一直在写 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 |