I am having an issue with sending a SocketIO message from a WSGI server to a SocketIO client. Messages going the other way (client to server) work fine without any issue. The code is in Python using the python-socketio
package and eventlet
to create a WSGI server. The server and the client run in different consoles on the same Windows machine. Messages are sent by clicking a button.
Here is what happens:
- In one console, the server is launched and a window with a button (that sends a message) appears.
- In the other console, the client is launched. A window with two buttons appears – one button initiates the connection to the server and the other button sends a message.
- The client’s “Connect” button is clicked and the connection is made without issue.
- The client’s “Send Msg” button is clicked and the sent data is printed in the server’s console (this works exactly as it should)
- The server’s “Send Msg” button is clicked. In the client console, nothing occurs for a while (I presume when the server polls again) and then the client’s disconnect() function executes (this is not what is expected)
The client console displays messages slightly differently depending on whether the client of the server sends the first message.
- If the server sends the first message, then when the client sends it’s message only the print statement from the disconnect() function is displayed.
- If the client sends the first message, then when the server sends it message, “packet queue is empty, aborting” is displayed followed by the print statement in the disconnect() function.
Why is the client not receiving the messages emitted from the server?
Here is complete server and client code that manifests the issue:
Server code:
from PyQt5.QtWidgets import QPushButton, QDialog, QApplication
import socketio, sys, eventlet
from threading import Thread
class My_Class(QDialog):
def __init__(self, parent=None):
super(My_Class, self).__init__(parent)
self.setWindowTitle("My SocketIO Server")
self.resize(300,150)
self.move(300, 200)
self.btn1 = QPushButton(self)
self.btn1.setText('Send Msg')
self.btn1.move(100,75)
self.btn1.clicked.connect(send_message_to_client)
self.show()
if __name__ == '__main__':
sio = socketio.Server(async_mode='eventlet')
def start_listening():
eventlet.wsgi.server(eventlet.listen(('', 5000)), serverapp)
@sio.event
def connect(sid, environ):
print('\nConnected with SID', sid)
def send_message_to_client():
print('\nSending from Button')
sio.emit('Message_from_server', {"Message 1": "Hello"})
@sio.event
def message_from_client(sid, data):
print('\nThis message came from the Client.', data, '\n')
serverapp = socketio.WSGIApp(sio, static_files={'/': {'content_type': 'text/html', 'filename': 'index.html'}})
thread = Thread(target = start_listening, args=())
thread.start()
app = QApplication(sys.argv)
form = My_Class()
form.show()
sys.exit(app.exec_())
Here is the client code:
from PyQt5.QtWidgets import QPushButton, QDialog, QApplication
import socketio, sys
class My_Client(QDialog):
def __init__(self, parent=None):
super(My_Client, self).__init__(parent)
self.setWindowTitle("My SocketIO Clent")
self.resize(300,150)
self.move(700, 200)
self.btn1 = QPushButton(self)
self.btn1.setText('connect')
self.btn1.move(50,75)
self.btn1.clicked.connect(connect)
self.btn2 = QPushButton(self)
self.btn2.setText('Send Msg')
self.btn2.move(175,75)
self.btn2.clicked.connect(send_message_from_client)
self.show()
if __name__ == '__main__':
sio = socketio.Client()
def connect():
sio.connect('http://localhost:5000')
print('\nConnection established using SID', sio.sid)
@sio.event
def message_from_server(sid, data):
print('\nMessage from server received with ', data)
def send_message_from_client():
print('\nMessage sent from Client')
sio.emit('message_from_client', {'Message': 'Hello World'})
@sio.event
def disconnect():
print('\nDisconnected from server\n')
app = QApplication(sys.argv)
form = My_Client()
form.show()
sys.exit(app.exec_())