简体   繁体   English

Flask中的Socket.io:来自外部源的数据

[英]Socket.io in flask: Data from external source

I have a web application and need to continuously display the actions going on in the backend on the browser. 我有一个Web应用程序,需要在浏览器的后端连续显示正在进行的操作。 I have been trying to use socket.io in Flask. 我一直在尝试在Flask中使用socket.io。 But I need to get the data to be displayed from other Python modules in my project. 但是我需要从项目中的其他Python模块获取要显示的数据。 So, I tried to make a socket connection between Flask and the external module from which I will be getting data to be displayed on the browser(without any delay). 因此,我尝试在Flask和外部模块之间建立套接字连接,从中我将获得要在浏览器中显示的数据(没有任何延迟)。

@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) is printing data on the console. print c.recv(1024)在控制台上打印数据。 But the same data is not getting reflected on the browser. 但是,相同的数据没有反映在浏览器上。 It's throwing this error - 引发此错误-

error: [Errno 98] Address already in use 错误:[Errno 98]地址已在使用中

This means it's failing at emit after print c.recv(1024) . 这意味着它在print c.recv(1024)之后无法emit What could be going wrong? 可能出什么问题了? My first doubt is if this kind of connection is allowed. 我的第一个疑问是是否允许这种连接。 I mean, can we have a socket connection created inside socket.io in Flask? 我的意思是,我们可以在Flask的socket.io内部创建套接字连接吗? Else, what is the best solution to display the backend actions on the browser continuously using Flask? 否则,什么是使用Flask在浏览器上连续显示后端操作的最佳解决方案? I also have the web application with Django. 我也有带有Django的Web应用程序。 Any solution for my use case with either Flask or Django will be appreciated (preferably Django). 我的Flask或Django用例的任何解决方案都将受到赞赏(最好是Django)。

The problem is that each time a client sends the event named my event to your server, you will try to start a new socket server on port 12345. Obviously this is only going to work the first time. 问题在于,每次客户端将名为my event的事件发送到您的服务器时,您都将尝试在端口12345上启动新的套接字服务器。显然,这仅在第一次使用时有效。

Have you seen the Emitting from an External Process section in the documentation? 您是否在文档中看到了“ 来自外部流程排放”部分?

The idea is that you can emit events to clients from any auxiliary process, which is exactly what you need. 这个想法是,您可以从任何辅助过程向客户端发出事件,这正是您所需要的。 The solution involves installing a message queue (Redis, RabbitMQ), to which the Flask-SocketIO server and the external processes that need to have emit powers connect to. 该解决方案涉及安装消息队列(Redis,RabbitMQ),Flask-SocketIO服务器和需要发射功率的外部进程连接到该消息队列。

Using the answer given by Miguel, I could find an appropriate solution. 使用Miguel给出的答案,我可以找到合适的解决方案。 In the external script, we need to create a SocketIO object as follows: 在外部脚本中,我们需要创建一个SocketIO对象,如下所示:

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

Then I can use emit to send the data to be displayed on the front end. 然后,我可以使用emit发送要显示在前端的数据。

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

fn()

And on the frontend, 在前端,

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>";
    });
});

Finally, on the Flask server side, we need to create the SocketIO object as follows: 最后,在Flask服务器端,我们需要创建SocketIO对象,如下所示:

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

Then run Flask with socketio.run(app,host='<ip>',port=<port>) 然后使用socketio.run(app,host='<ip>',port=<port>)运行Flask

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM