How to emit a websocket message from outside the websocket endpoint?

I am creating a website using Flask in which I am also using Websockets using Flask-socketIO , but there is one thing I don't understand.

I have created a chat functionality. When one user sends a message, I use websockets to send that message to the server, after which I send a message to another user from the same call:

@socketio.on('newPM', namespace='/test')
@login_required_with_global
def io_newMessage(theJson):
    emit('message', {'message': theJson['message']}, room=str(theJson['toUserId']))

      

But let's say that I want to send a message to the user when the file has been saved. This means I need to issue a message from the view where the POSTED file is. So according to the flask_socketio docs I can add a namespace to emit. So I wrote the following:

@app.route('/doc', methods=['POST'])
@login_required
def postDoc():
    saveDocument(request.files['file'], g.user.id)
    emit('my response', {'data': 'A NEW FILE WAS POSTED'}, room=current_user.id, namespace='/test')
    return jsonify({'id': str(doc.id)})

      

But seeing the stack at the bottom, there is a namespace problem; werkzeug has AttributeError: 'Request' object has no attribute 'namespace'

.

Does anyone know what I am doing wrong here? Or is it a bug in flask_socketio? All advice is appreciated!

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 758, in decorated_view
    return func(*args, **kwargs)
  File "/home/vg/app/views.py", line 768, in emitNotificationCount
    emit('menuInit', emitJson, room=current_user.id, namespace='/test')
  File "/usr/local/lib/python2.7/dist-packages/flask_socketio/__init__.py", line 444, in emit
    return request.namespace.emit(event, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 338, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: 'Request' object has no attribute 'namespace'

      

+3


source to share


1 answer


Quoting from Miguel Greenberg's answer on the open issue page on Flask-SocketIO GitHub :

If you want to fix from the normal route you need to use socketio.emit (), only socket handlers have socketio context you need to call plain emit ().



So, as an example:

from flask_socketio import SocketIO

app = Flask(__name__)
app.config.from_object('config')
socketio = SocketIO(app)

@app.route('/doc', methods=['POST'])
def postDoc():
    saveDocument(request.files['file'], g.user.id)
    socketio.emit('my response', {'data': 'A NEW FILE WAS POSTED'}, room=current_user.id)
    return jsonify({'id': str(doc.id)})

      

+9


source







All Articles