Muatik
Muatik

Reputation: 4171

emitting from thread using flask's socketio extension

I want to emit a delayed message to a socket client. For example, when a new client connects, "checking is started" message should be emitted to the client, and after a certain seconds another message from a thread should be emitted.

@socket.on('doSomething', namespace='/test')
def onDoSomething(data):
  t = threading.Timer(4, checkSomeResources)
  t.start()
  emit('doingSomething', 'checking is started')

def checkSomeResources()
  # ...
  # some work which takes several seconds comes here
  # ...
  emit('doingSomething', 'checking is done')

But the code does not work because of context issue. I get

RuntimeError('working outside of request context')

Is it possible to make emitting from a thread?

Upvotes: 5

Views: 2993

Answers (1)

Miguel Grinberg
Miguel Grinberg

Reputation: 67492

The problem is that the thread does not have the context to know what user to address the message to.

You can pass request.namespace to the thread as an argument, and then send the message with it. Example:

@socket.on('doSomething', namespace='/test')
def onDoSomething(data):
    t = threading.Timer(4, checkSomeResources, request.namespace)
    t.start()
    emit('doingSomething', 'checking is started')

def checkSomeResources(namespace)
    # ...
    # some work which takes several seconds comes here
    # ...
    namespace.emit('doingSomething', 'checking is done')

Upvotes: 4

Related Questions