2017-08-10 26 views
1

我有一个Web应用程序,需要持续显示浏览器后端进行的操作。我一直试图在Flask中使用socket.io。但我需要从我的项目中的其他Python模块获取数据。所以,我试图在Flask和外部模块之间建立一个套接字连接,从中我将获得要在浏览器上显示的数据(没有任何延迟)。烧瓶中的Socket.io:来自外部源的数据

@socketio.on('my event') 
def server(message): 
    s = socket.socket()  
    print "Socket successfully created" 
    port = 12345    
    s.bind(('', port))   
    print "socket binded to %s" %(port) 
    s.listen(5)  
    print "socket is listening"   
    while True: 
     c, addr = s.accept()  
     print 'Got connection from', addr 
     print c.recv(1024) 
     emit('my response', {'data': c.recv(1024)}) 
     c.close() 

print c.recv(1024)正在控制台上打印数据。但相同的数据没有反映在浏览器上。它抛出这个错误 -

error: [Errno 98] Address already in use

这意味着它print c.recv(1024)后未能在emit。可能会出现什么问题? 我的第一个疑问是如果这种连接是允许的。我的意思是,我们可以在Flask中的socket.io中创建套接字连接吗? 否则,连续使用Flask在浏览器上显示后端操作的最佳解决方案是什么?我也有Django的Web应用程序。任何与Flask或Django使用案例的解决方案都将被赞赏(最好是Django)。

回答

2

问题是,每次客户端向您的服务器发送名为my event的事件时,您都会尝试在端口12345上启动一个新的套接字服务器。显然这只是第一次运行。

您是否看到过文档中的Emitting from an External Process部分?

这个想法是,您可以从任何辅助进程向客户端发送事件,这正是您所需要的。该解决方案涉及安装消息队列(Redis,RabbitMQ),Flask-SocketIO服务器和需要发出电源的外部进程连接到该队列。

+0

非常感谢Miguel。 – phanny

2

使用Miguel给出的答案,我可以找到一个合适的解决方案。在外部脚本,我们需要如下创建SocketIO对象:

socketio = SocketIO(message_queue='redis://') 

那么我可以用emit发送到显示在前端的数据。

def fn(): 
    socketio.emit('my response', {'data': 'ur data goes here'}) 

fn() 

而且在前端,

var socket = io.connect('http://' + document.domain + ':' + location.port); 
socket.on('connect', function() { 
socket.on('my response', function(msg) { 
    $('#log').append('<p>Received: ' + msg.data + '</p>'); 
    document.getElementById('<div_id>').innerHTML += msg.data + "<br>"; 
    }); 
}); 

最后,在烧瓶服务器端,我们需要创建SocketIO对象如下:

socketio = SocketIO(app, message_queue='redis://') 

然后用socketio.run(app,host='<ip>',port=<port>)

运行瓶