question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

If i emit a event in a `Thread`, the client can't get the event.

See original GitHub issue

I’m trying to do as following.

(1) send message from client to server, add the message into a Queue on the server side.
(2) the server process the data in the queue in a Thread. 
(3) The server emit a response to the client after processing data

The server.py is as follows:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import eventlet
import socketio
from time import sleep
import threading
import queue
q = queue.Queue()


sio = socketio.Server(logger=True, engineio_logger=True)
app = socketio.WSGIApp(sio, static_files={
    '/': {'content_type': 'text/html', 'filename': 'index.html'}
})


@sio.event
def connect(sid, environ):
    print('new client connect ', sid)


@sio.event
def request(sid, data):
    sio.emit('client_response', data)
    print("(3)"+str(data))


@sio.event
def response(sid, data):
    print("(2) "+str(data))
    info = {"sid": sid, "data": data}
    q.put(info)


def process_data():
    while True:
        if not q.empty():
            item = q.get()
            data = item.get('data', "")
            sid = item.get('sid', None)
            print("data here: %s" % data)
            sleep(1)
            data = "data send from server "+str(data)
            request(sid, data)



@sio.event
def disconnect(sid):
    print('disconnect ', sid)


threading.Thread(target=process_data).start()

if __name__ == '__main__':
    eventlet.wsgi.server(eventlet.listen(('x.x.x.x', 8081)), app)

The client.py is as follows:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socketio
sio = socketio.Client(logger=True)
sio.connect('http://x.x.x.x:8081')


@sio.event
def connect():
    print('connection established')


@sio.event
def client_request(data):
    print("(1) %s" % data)
    sio.emit('response', data)


@sio.event
def client_response(data):
    print("(4) %s" % data)




if __name__ == '__main__':
    for i in range(0, 2):
                client_request("id: "+str(i))
    sio.wait()

The server can get the message send from client, and can process data. But after the server do sio.emit('client_response', data) in the Thread, the client can’t receive the processed data from server (If i do the emit in the main thread, it works well ). Could you please give me some suggestions about this please? Thanks a lot. The log is as follows: On server side:

% python server.py
Server initialized for eventlet.
(617) wsgi starting up on http://x.x.x.x:8081
(617) accepted ('x.x.x.x', 44067)
a721b61ce62345d399db3006ccf2a769: Sending packet OPEN data {'sid': 'a721b61ce62345d399db3006ccf2a769', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
new client connect  a721b61ce62345d399db3006ccf2a769
a721b61ce62345d399db3006ccf2a769: Sending packet MESSAGE data 0
x.x.x.x - - [22/Sep/2020 16:47:36] "GET /socket.io/?transport=polling&EIO=3&t=1600764456.5817175 HTTP/1.1" 200 371 0.026230
(617) accepted ('x.x.x.x', 44068)
a721b61ce62345d399db3006ccf2a769: Received request to upgrade to websocket
a721b61ce62345d399db3006ccf2a769: Upgrade to websocket successful
a721b61ce62345d399db3006ccf2a769: Received packet PING data None
a721b61ce62345d399db3006ccf2a769: Sending packet PONG data None
a721b61ce62345d399db3006ccf2a769: Received packet MESSAGE data 2["response","id: 0"]
received event "response" from a721b61ce62345d399db3006ccf2a769 [/]
(2) id: 0
a721b61ce62345d399db3006ccf2a769: Received packet MESSAGE data 2["response","id: 1"]
data here: id: 0
received event "response" from a721b61ce62345d399db3006ccf2a769 [/]
(2) id: 1
emitting event "client_response" to all [/]
a721b61ce62345d399db3006ccf2a769: Sending packet MESSAGE data 2["client_response","data send from server id: 0"]
(3)data send from server id: 0
data here: id: 1
emitting event "client_response" to all [/]
a721b61ce62345d399db3006ccf2a769: Sending packet MESSAGE data 2["client_response","data send from server id: 1"]
(3)data send from server id: 1

On client side:

% python client.py
Engine.IO connection established
Namespace / is connected
(1) id: 0
Emitting event "response" [/]
(1) id: 1
Emitting event "response" [/]
Engine.IO connection dropped
Connection failed, new attempt in 1.03 seconds
Engine.IO connection established
Namespace / is connected
connection established
Reconnection successful
Engine.IO connection dropped

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:14 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
miguelgrinbergcommented, Mar 5, 2021

You can’t use greenlet frameworks with code that hasn’t been written specifically for them. Monkey patching replaces a big portion of the standard library with compatible code. If you have other code that is blocking you have to fix it so that it is greenlet friendly and does not block. If you rely on third party libraries that is unlikely to have a solution unless you find another library that supports greenlets or write one yourself.

0reactions
stansotncommented, Apr 21, 2021

Right, I made sure all calls to the multiprocessing queue are non-blocking, now everything runs without monkeypatching!

# A non-blocking multiprocessing queue get example.
m = None
try:
    m = tx_queue.get(False)
except queue.Empty:
    pass
return m

ps: I noticed monkeypatching breaks the ability to generate coverage.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Flask-soketio application does not handle new emit event from ...
When the server receives an event from a client (let's say your exec_event ), it dispatches the event by calling the appropriate handler....
Read more >
Python Multithreading Tutorial: Event Objects between Threads
Event object is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it...
Read more >
Using Event Emitters in Node.js - DigitalOcean
Event emitters are objects in Node.js that trigger an event by sending a message to signal that an action was completed.
Read more >
The event loop - JavaScript - MDN Web Docs - Mozilla
JavaScript has a runtime model based on an event loop, which is responsible for executing the code, collecting and processing events, ...
Read more >
Event system | Bitbucket Data Center and Server 8.2
The event queue can fill up if events are being raised faster than they can be processed. This is most commonly caused by...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found