python socketio socketio.emit,Python-Flask-SocketIO从线程发送消息:并非始终有效

I am in the situation where I receive a message from the client. Within the function that handles that request (@socketio.on) I want to call a function where some heavy work is done. This should not result in blocking the main thread and the client is thought to be informed once the work is done. Thus I start a new thread.

Now I encounter a really strange behavior:

The message never reaches the client. However, the code reaches that particular spot where the message is sent.

Even more surprising is the fact that if there is nothing happening in the thread except for the message being sent to the client then the answer actually finds its way to the client.

To sum it up:

If something computationally intensive happens before the message is sent it is not being delivered, otherwise it is.

Like it is said here and here, sending messages from a thread to the clients is not a problem at all:

In all the examples shown until this point the server responds to an event sent by the client. But for some applications, the server needs to be the originator of a message. This can be useful to send notifications to clients of events that originated in the server, for example in a background thread.

Here is a sample code. When removing the commenting sharps (#) the message ('foo from thread') does not find its way to the client, otherwise it does.

from flask import Flask

from flask.ext.socketio import SocketIO, emit

app = Flask(__name__)

socketio = SocketIO(app)

from threading import Thread

import time

@socketio.on('client command')

def response(data):

thread = Thread(target = testThreadFunction)

thread.daemon = True

thread.start()

emit('client response', ['foo'])

def testThreadFunction():

# time.sleep(1)

socketio.emit('client response', ['foo from thread'])

socketio.run(app)

I am using Python 3.4.3, Flask 0.10.1, flask-socketio1.2, eventlet 0.17.4.

This sample can be copied and pasted in a .py file and the behavior can be instantly reproduced.

Can somebody explain this strange behavior?

Update

It seems to be a bug of eventlet. If I do:

socketio = SocketIO(app, async_mode='threading')

It forces the application not to use eventlet although it is installed.

However, this is not an applicable solution for me as using 'threading' as async_mode refuses to accept binary data. Every time I send some binary data from the client to the server it says:

WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance.

The third option, using gevent as the async_mode does not work for me as well as gevent does not have support for python 3 yet.

So any other suggestions?

解决方案

I managed to resolve the issue by monkeypatching several Python functions which causes Python to use the eventlet functions instead of the native ones. This way background threads work fine with eventlet.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值