2017-07-28 108 views
0

编辑:作为问题的性质变得更加清晰Flask.SocketIO未能异步地将数据发送到登记的与会时异步模式“线程”

我想实现一个非常简单的socket.io更新标题连接将广播事件从Flask服务器发送到Javscript客户端。第一个服务器消息到达客户端,但没有更多。在服务器端,它会随着周期性数据更新而持续发出呼叫,但客户端在第一次之后从不会收到任何消息。

这里是JavaScript客户端(从阵营应用程式提取相关行):

var io=require('socket.io-client') 
var socket = io.connect(); 
socket.on('connect', function() { 
    console.log('Connection established'); 
}); 


socket.on('message', function(data){ 
    console.log('Message received'); 
    console.log(data); 
    //only gets called for the first message sent by the server 
} 

并将烧瓶服务器代码:

from flask_socketio import SocketIO, emit 
app = Flask(...) 
socketio = SocketIO(app, async_mode="eventlet") 
socketio.emit('message', "Test data", broadcast=True) 

#Update function called periodically with JSON data 
#of the form {"data": {...}} 
def update(data): 
    data = json.dumps(data) 
    socketio.emit('message', data, broadcast=True) 

客户机接收“测试数据”消息,但没有从update函数发送的消息。

编辑:我发现这个代码/usr/lib/python2.7/site-packages/socketio/base_manager.py

for sid in self.get_participants(namespace, room): 
      if sid != skip_sid: 
       if callback is not None: 
        id = self._generate_ack_id(sid, namespace, callback) 
       else: 
        id = None 
       self.server._emit_internal(sid, event, data, namespace, id) 

在调试器中我看到它代表socket.io的SID值客户端,当服务器发送原始“测试数据”并发送后续更新时。因此,服务器仍然将客户端视为参与者,它必须以相同的ID开始,但客户端不会收到任何后续更新。如果我在更新函数发出任何事件之前在一行中发出两条消息,则客户端会获取它们。但是更新函数内部发出的任何事件都不会被客户端接收到。

我认为这是某种范围问题,但如果服务器仍然看到客户端作为参与者,当更新方法内发生事件时,似乎不存在范围问题。我也在一个答案中尝试了建议,将socketio对象传递给更新函数,并且我得到了相同的行为。我不明白为什么客户端不会仅仅因为服务器从特定函数发送它们而接收事件,而当该函数的执行上下文显示客户端仍然是参与者时。

这是一个简单的例子,我可以想象,我做的事情与我在网上看到的每个例子中都看到了一样。很明显,我错过了一些东西。

回答

0

我想是你错过收到客户端的方法... 请参阅socket.io

socket.on('test', function (data) { console.log(data); });

+0

谢谢,但我不确定我明白你的建议。我在客户端使用了socket.on('message',function(data){...},是不是我需要接收“消息”事件?这是我正在发送的事件服务器端,客户端收到它时,我第一次发出它,而不是随后的时间,从更新函数调用 – MidnightJava

+0

对不起,但我在nodeJS中使用套接字..你在更新函数中获取socketio。尝试在更新函数中传递socketio作为参数。 –

+0

好主意,但它没有做到这一点。谢谢你的帮助。 – MidnightJava

0

我能够让它通过设置async_mode为True工作时,我在创建SocketIO实例Flask服务器。

也就是说,我改变socketio = SocketIO(app, async_mode="eventlet")socketio = SocketIO(app, async_mode="threading")

我不知道为什么它不与eventlet,这似乎是首选模式正常工作,因为线程是最后一个尝试,如果你不指定它根据文档字符串。

如果我更精确地理解threading和其他异步模式之间的实现差异,也许我可以弄清楚为什么只有在我使用文档所说的最低性能模式时才起作用。也许我错过了它,但我没有在文档中看到这样的解释,只是对不同模式之间依赖性差异的模糊讨论。