The documentation says
"In all the examples shown until this point the server responds to an event sent by the client. But for some applications, the server needs to be the originator of a message. This can be useful to send notifications to clients of events that originated in the server, for example in a background thread. The socketio.send() and socketio.emit() methods can be used to broadcast to all connected clients:
def some_function():
socketio.emit('some event', {'data': 42})
Note that socketio.send() and socketio.emit() are not the same functions as the context-aware send() and emit(). Also note that in the above usage there is no client context, so broadcast=True is assumed and does not need to be specified."
This is not really working; my client only receives events if socketio.emit used in context otherwise the client wouldn't listen. Moreover, when I used the emit(), send(), and even the disconnect() functions, I get 'working outside of application context' error. All I am trying to do is to shutdown the server and its clients using a regular function outside of context. Any idea on how I could do that? Thanks!
I don't understand what the problem is, sorry. Can you show the code that is failing and the complete stack trace, please?
All I am trying to do is to shutdown the server and its clients using a regular function outside of context.
Do you have the message_queue parameter set on your initialization?
ie : socket = SocketIO(app, message_queue="redis://localhost:6379/0")
Flask-SocketIO can send message outside of context, but it needs be on the same thread/process if you don't specify your message queue (so no background thread or outside service).
Don't hesitate to correct me @miguelgrinberg if I'm wrong.
@miguelgrinberg This is my code. I am having issues disconnecting the clients on demand and emitting messages outside of application context. read my comments
def Foo ():
app = Flask(__name__)
io = SocketIO(app) # engineio_logger=True)
class Bar:
def __init__(self, *args, **kwargs):
self.app = app
self.io = io
@io.on('connect')
def connect():
print('connection established')
io.emit('downlink', {'connection': 'good'})
@io.on('disconnect')
def disconnecting():
disconnect() #emits disconnect message to all clients
print('all clients are disconnected!')
io.stop() #raise SystemExit which halts the server
print('flask app disconnected successfully!')
def close(self):
io.emit('kill me', {}) #client should emit disconnect event to the server but this message's not been delivered to the client
#disconnect() #this generates RuntimeError: working outside of application context
return Bar
The following is the client node js code
1 var io = require('socket.io-client') ;
2 var socket = io.connect('http://localhost:5000', {transports: ['websocket']});
6 /****** client.js ******/
7 socket.on('connect', function () {
8 console.log('connected');
9 socket.emit('uplink', {'from': 'node'});
25 socket.on('disconnect', function() {
29 socket.disconnect(); //halts the client thread
30 console.log('socket disconnected successfully!');
31 });
33 socket.on('downlink', function (data) {
34 console.log('downlink: ', data);
35 });
37 socket.on('kill me', function (data) {
38 socket.emit('disconnect', {});
39 });
Can you also paste the disconnect function as well?
@PierrePaul the disconnect function is imported from flask_socketio
The disconnect function remove a single client (sid) from all the rooms inside a single namespace. If you don't have the application context (the request object), there is no way to know the user sid (socket-id) you want to disconnect.
By reading your comment though #emits disconnect message to all clients, I'm guessing what you want to do is :
io.emit('user-disconnected', {sid: flask.request.sid})
Unless you wanted to disconnect all clients when a single client disconnect?
I only have one client connected right now. I cannot shutdown my server because io.stop() won't work until this client shutdown.
io.emit('user-disconnected', {sid: flask.request.sid}) does not work. it says flask has no attribute 'request'
I must say that I am running the client and io.run using two different threads. This might have been causing the issue with the application context and I am not sure how to fix it!
@gtatyous93 the code that you showed includes a close function, but you are not showing the code that calls it.
I am not sure how would that effect it but eventually I want to be able to shutdown the server using object.close(). Currently, I am testing it using the following code:
if __name__ == '__main__':
with Foo()() as foo:
time.sleep(2);
and the __exit__(self) function calls self.close()
Shutdown the server? The disconnect function disconnects a user, it has nothing to do with the server.
@PierrePaul
I had a same problem
socket = SocketIO(app, message_queue="redis://localhost:6379/0")
This worked for me :)
Most helpful comment
Do you have the
message_queueparameter set on your initialization?ie :
socket = SocketIO(app, message_queue="redis://localhost:6379/0")Flask-SocketIO can send message outside of context, but it needs be on the same thread/process if you don't specify your message queue (so no background thread or outside service).
Don't hesitate to correct me @miguelgrinberg if I'm wrong.