3

Flask-SocketIO is giving me some trouble. I am trying to initialize private chat rooms with the following code:

@socketio.on('join', namespace='/join')
def on_join(receiver_name):
    username = session['username']
    join_room(receiver_name)  # start a chat room with the receiver's username
    send(username + ' is now connected.', room=receiver_name)

Unfortunately, I am getting errors such as AttributeError: 'Request' object has no attribute 'sid'. Even when I specifically specify request.sid I get an error. When I plug in something random for the sid field in join_room, I then get a namespace error. I have ensured that I am importing everything necessary etc.

Here is the specific error message.

[2017-10-04 10:02:48,297] ERROR in app: Exception on /start_chat [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/agaidis/Desktop/challenge-backend-master/challenge-eng-base-master/backend-python/app.py", line 132, in start_chat
    on_join(friend_username)
  File "/Users/agaidis/Desktop/challenge-backend-master/challenge-eng-base-master/backend-python/app.py", line 152, in on_join
    join_room(receiver_name)  # start a chat room with the receiver's username
  File "/usr/local/lib/python3.6/site-packages/flask_socketio/__init__.py", line 756, in join_room
    sid = sid or flask.request.sid
  File "/usr/local/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: 'Request' object has no attribute 'sid'
127.0.0.1 - - [04/Oct/2017 10:02:48] "POST /start_chat HTTP/1.1" 500 -
peachykeen
  • 4,143
  • 4
  • 30
  • 49

1 Answers1

4

You are invoking the on_join() function yourself from an HTTP route. That's not how this is supposed to work. The Socket.IO events are invoked when the client calls emit() on that event. The request.sid variable only exists in the context of a Socket.IO event handler, that will not be present in an HTTP handler.

Based on your stack trace, I think you need to change the start_chat route from HTTP to Socket.IO. The client will need to request to join the chat by making an emit() call instead of sending an HTTP request.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Thank you! I am a noob to Flask and Socket.IO. In order to instantiate multiple rooms, clients open up new socket connections in the client-side code, correct? The web-page they see will be the normal HTML with whatever stuff is specific to their open socket? – peachykeen Oct 05 '17 at 04:43
  • 1
    You can associate a single client connection with multiple rooms, no need to create multiple connections. It is totally okay to call `join_room()` multiple times for the same client. – Miguel Grinberg Oct 05 '17 at 18:06