V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
smallgoogle
V2EX  ›  Python

很想知道 Python 有没有类似 PHP 的 workerman 的库

  •  
  •   smallgoogle · 2019-01-30 06:17:41 +08:00 · 3839 次点击
    这是一个创建于 2155 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近一直在写 python 方面的东西,一直都在 websocket 通讯上卡住;

    我很想知道 python 有没有好像 php 的 workerman 的库,可以直接使用 websocket,然后写业务逻辑就好了;

    我现在是 flask + flask_socketio,可是碰到很尴尬的事情,发现 SocketIO 在前端好像是轮询方式一样,不停的在请求;

    其实我只是想要一个长连接而已;

    其次是发现我用 flask + flask_socketio 构架,web 也是他,socket 也是他,到底我怎么在 web 的后端业务逻辑里面去使用 socket 给用户主动推送消息呢?比如 php 的 websocket 里 GatewayClient 一样,只要直接调用就可以后端给前端发消息了;

    这简直是我最大的挣扎点,各位前辈请轻拍,各种文档资料 github 案例都给我吧,我不怕麻烦,不嫌弃案例多;
    只要能帮助到,我愿意一个个的看,一个个的深究; 感谢。。。。。

    第 1 条附言  ·  2019-01-30 06:51:18 +08:00
    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给前端。让前端知道,喔,有数据进入了,大概这个意思;

    14 条回复    2019-08-12 04:12:33 +08:00
    PulpFunction
        1
    PulpFunction  
       2019-01-30 06:49:52 +08:00 via Android
    李辉大佬肯定会 这么早就写代码了???
    est
        2
    est  
       2019-01-30 08:10:04 +08:00 via Android
    py 有 gunicorn worker,php 有 fpmworker

    都是多进程在服务器跑。那么问题来了,你如何判断客户长连接连上哪个进程的?

    我好奇 woekeeman 如何解决这个问题的?
    Trim21
        3
    Trim21  
       2019-01-30 08:10:37 +08:00 via iPhone
    用过 aiohttp 里面的 socketio,应该是差不多的用法吧(

    在 flask 的路由函数里跟 background thread 函数里面一样,直接 emit 出去不可以吗?
    ratazzi
        4
    ratazzi  
       2019-01-30 08:19:44 +08:00 via iPhone
    socketio 支持几种模式,轮询是其中一种,要看是什么原因导致没用 websocket
    rogwan
        5
    rogwan  
       2019-01-30 08:28:31 +08:00 via Android
    @smallgoogle
    直接用 Flask-Sockets 就可以,前端基本上都直接支持 websocket 了

    cc @est
    没法知道是哪个进程连上的吧,还有多终端连接的问题,这个要实现,要么要加上用户系统来判断,新建一个 ws 断开老的 ws,否则很难准确判断。
    vZexc0m
        6
    vZexc0m  
       2019-01-30 16:33:38 +08:00
    以前用 tornado 写过相关的代码,具体识别用户连接的方法是客户端建立 websocket 连接的时候在 URL 上带上登录凭证,然后服务端将用户和 websocket 连接对应起来,如果要向某个用户主动推送消息,只需要找到用户的 websocket 连接进行发送消息即可。
    smallgoogle
        7
    smallgoogle  
    OP
       2019-01-31 03:00:52 +08:00
    @est workerman 有一个唯一客户端 ID 作为标识。
    est
        8
    est  
       2019-01-31 08:06:01 +08:00 via Android
    @smallgoogle 所以其实楼主代码里没看到相关逻辑。
    769932247
        9
    769932247  
       2019-02-13 14:12:02 +08:00
    楼主还在做么,我最近也在写,遇到一些问题
    lsls931011
        10
    lsls931011  
       2019-02-14 17:40:34 +08:00
    像我们 php 程序员是使用 swoole 的,哈哈
    lakechan96
        11
    lakechan96  
       2019-02-17 16:56:47 +08:00
    @smallgoogle SocketIO 有 sid 做唯一 ID

    当发送到名称为 sid 的 room 时等同于发送给指定用户

    但是在 @socketio.* 的 context 之外,你需要自己自己维护 sid 来调用 emit 发送,在 context 之内可以直接使用 request.sid
    smallgoogle
        12
    smallgoogle  
    OP
       2019-02-18 01:57:42 +08:00
    @769932247 什么问题?
    shange123
        13
    shange123  
       2019-02-19 10:52:36 +08:00
    使用 tornado 啊,自带 websocket
    miao666
        14
    miao666  
       2019-08-12 04:12:33 +08:00 via iPhone
    @est workerman 应该是单进程,多线程的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1046 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 19:53 · PVG 03:53 · LAX 11:53 · JFK 14:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.