服务器创建后 Python SocketIO 发出事件

Posted

技术标签:

【中文标题】服务器创建后 Python SocketIO 发出事件【英文标题】:Python SocketIO emitting event after server creation 【发布时间】:2016-09-09 21:33:43 【问题描述】:

我有一个使用 php 和一个修改文件夹的 python 脚本的 web 项目。 我想基于例如在网站上执行一些 javascript。在 python 脚本中创建文件夹。

我的想法是使用 python socketio。我有基本的连接通知工作,并且网站上的 js 发出的信息也由 js 处理。

问题是在启动 eventlet 服务器后我无法发出任何事件。 我尝试设置异步模式,但没有得到想要的结果。

到目前为止,这是我的代码:

import socketio
from flask import Flask, render_template
import eventlet

import sys

sio = socketio.Server(async_mode='eventlet')
app = Flask(__name__)

@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)
    sio.emit('channel', 'new connection')
    sys.stdout.flush()

@sio.on('mes')
def message(sid, data):
    print('message ', data)
    sys.stdout.flush()

app = socketio.Middleware(sio)

eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

# create folder HERE and emit event which will be sent to browser

更新:

我开始使用如下代码中的线程: (使用这样的线程有问题吗?或者其他更好的方法?)

import socketio
from flask import Flask, render_template
import eventlet

import sys
import thread
import time

sio = socketio.Server(async_mode='gevent')

@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)
    sio.emit('channel', 'new connection')
    sys.stdout.flush()

@sio.on('mes')
def message(sid, data):
   print('message ', data)
   sio.emit('channel', 'yeah')
   sys.stdout.flush()

from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
app = socketio.Middleware(sio)

def worker( threadName ):
   count = 1
   while count > 0:
      time.sleep(1)
      # trying to emit message HERE
      sio.emit('mes', 'foo ' + str(count))
      print "working " + str(count)
      sys.stdout.flush()
      count += 1

def server( threadName ):
   print "server starting"
   sys.stdout.flush()
   pywsgi.WSGIServer(('', 8000), app, handler_class=WebSocketHandler).serve_forever()

try:
   thread.start_new_thread( worker, ("Thread-1", ) )
   thread.start_new_thread( server, ("Thread-2", ) )
except:
   print "Error: unable to start thread"

while 1:
   pass

现在的问题是 sio.emit('mes', 'foo ' + str(count)) 发出消息 - 但浏览器仅每 20~30 秒捕获一次,然后处理所有丢失的事件。从开发控制台查看带有框架的图片。

【问题讨论】:

不确定我是否理解。您是否尝试在服务器启动后立即在底部运行代码?这就是现在的工作方式,服务器创建调用没有返回。 @Miguel 是的,这就是我想要做的。我使用线程用我的新代码更新了我的问题 - 使用这样的线程是否正确?你知道为什么没有立即收到新活动吗? 您实际上并不需要将服务器置于后台线程中。只需在主线程上启动服务器之前启动工作线程。除此之外,我能想到的就是你应该使用gevent.sleep() 而不是time.sleep() 将问题剥离为一个代码和一个问题以获得明确的答案。否则,对于当前方法:删除 eventlet 或 gevent。两者都在同一个过程中自找麻烦。还要在开头添加eventlet/gevent.monkey_patch(),然后再执行任何其他导入。 @Miguel 没有将服务器放在单独的线程中似乎解决了我的问题。感谢您的 cmets 和帮助。但是gevent.sleept()didd 似乎没有与time.sleep() 相同的效果 - 工人不再输出任何东西。 【参考方案1】:

通过@Miguel 的 cmets,我实现了我的目标。

我删除了似乎具有预期效果的服务器线程。现在,每次工作人员触发事件时,开发者控制台都会显示一个已发出的事件。

import socketio
import sys
import thread
import time

sio = socketio.Server(async_mode='gevent')

@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)
    sio.emit('channel', 'new connection')
    sys.stdout.flush()

@sio.on('mes')
def message(sid, data):
   print('message ', data)
   sio.emit('channel', 'yeah')
   sys.stdout.flush()

from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
app = socketio.Middleware(sio)

def worker( threadName ):
   count = 1
   while count > 0:
      time.sleep(5)
      sio.emit('mes', 'foo ' + str(count))
      print "working " + str(count)
      sys.stdout.flush()
      count += 1

try:
   thread.start_new_thread( worker, ("Thread-1", ) )
except:
   print "Error: unable to start thread"

print "server starting"
sys.stdout.flush()
pywsgi.WSGIServer(('', 8000), app, handler_class=WebSocketHandler).serve_forever()

【讨论】:

以上是关于服务器创建后 Python SocketIO 发出事件的主要内容,如果未能解决你的问题,请参考以下文章

来自异步芹菜工作者的 SocketIO 发出不工作

向所有客户端发出的 SocketIO 不起作用

向特定用户发出的 SocketIO(不为每个客户端使用单独的房间)

如何在服务器端发出 SocketIO 事件

以设定的时间间隔从 flask_socketio 服务器发出事件

使用 pytest 测试 flask-socketio 服务器发出的事件时出错