miguelgrinberg / Flask-SocketIO

Socket.IO integration for Flask applications.
MIT License
5.36k stars 890 forks source link

Flask-SocketIO returns [] on `get_received` function call #2063

Closed shivansh-vishwakarma closed 4 months ago

shivansh-vishwakarma commented 5 months ago

Flask-SocketIO's get_received(namespace=None) function is not returning the messages received from server. I am using SocketIOTestClient for writing test cases for the flask application. Went through the code seems like the get_received uses self.queue to get the events to emitted and couldn't find where the queue is being populated. Can someone help here?

miguelgrinberg commented 5 months ago

@shivansh-vishwakarma Please provide a complete and runnable example test that shows the problem and I'll investigate.

shivansh-vishwakarma commented 5 months ago

Hope this helps. Do let me know if you need anything that'll help you in the investigation

class TestSocketEmit(TestCase):
    def setUp(self):
        self.client = app.test_client()
        self.api_key = "API_KEY"
        self.socketio_test_client = SocketIOTestClient(app, socketio=socketio, headers={'x-api-key': self.api_key})
        self.socketio_test_client.connect(headers={'x-api-key': self.api_key})

    def test_websocket_emit(self):
        self.socketio_test_client.emit('your_event', {'data': 'test'})
        response = self.socketio_test_client.get_received()

    def tearDown(self):
        self.socketio_test_client.disconnect()

In the given code the response is[]

miguelgrinberg commented 5 months ago

How is this any different than the many tests in this repository's test suite? I wanted to see a complete and runnable example, because this feels like it is a problem in your own setup, not in this package. Please provide a complete example that includes the application to be tested.

shivansh-vishwakarma commented 5 months ago

@miguelgrinberg This should suffice the requirement. I've abstracted out the functionality of flask and socket to reproduce the same with minimal code. If we can make it work here, it'll work in my project as well.

https://github.com/shivansh-vishwakarma/flask-socket-scratch

shivansh-vishwakarma commented 5 months ago

One more thing that i noticed which abstracting the functionality was, If we emit an event to the main application server in the src code using SocketIO.emit() Then i get response in the get_received() method. but while doing it with SocketIOTestClient.emit() it doesn't work out. Might be helpful in the investigation.

miguelgrinberg commented 5 months ago

Okay, thanks. This is actually a different bug in Flask-SocketIO, I will have a fix in the next couple of days.

shivansh-vishwakarma commented 5 months ago

Also, Can you confirm if there is support to emit messages to a particular room using SocketIOTestClient and receive the messages from a particular room using get_received or some other function. I tried but couldn't find it.

miguelgrinberg commented 5 months ago

If the client is in the room, then any messages sent to that client should appear in the test client's get_received. If the client is not in the room, then the messages will not be sent to that client or test client.

miguelgrinberg commented 4 months ago

@shivansh-vishwakarma in the example you provided, your test sends this event:

self.socketio_test_client.emit('your_event', {'data': 'test'})

But your server does not have an event handler for your_event. What was the expected outcome in this case? As far as I can see, your test is incorrect. You are sending an unknown event to the server, so the test client gets no reply. I added this missing event handler and test started to pass:

socketio.on('your_event')
def your_event(data):
    emit('got it')

Am I missing anything?

shivansh-vishwakarma commented 4 months ago

No, your are correct. My bad @miguelgrinberg