pythonsocket.iopython-multithreadingflask-socketiopython-socketio

Python SocketIO, run socketio server in background


How can I start a SocketIO server and have it be listening in the background while I continue to execute code on the main thread?

Right now I am using the package python-socketio. I have also testedflask-socketio which using python-socketio anyway. https://python-socketio.readthedocs.io/en/latest/server.html

What I've mostly tried is starting the server with sio.start_background_task.

For example:

class SocketIOServer(socketio.AsyncNamespace):
  def __init__(self):
    super().__init__()
    self.sio = socketio.AsyncServer()
    self.sio.register_namespace(self)
    self.app = web.Application()
    self.sio.attach(self.app)
    self.task = None

  def run(self):
    web.run_app(self.app, port=8080)

  def start(self):
    self.task = self.sio.start_background_task(self.run)

I tried the above and multiple variations like using Flask, Tornado, etc.

To be more clear this is basically what I want to do:

if __name__ == '__main__':
  # ...
  # start app, e.g. -> web.run_app(self.app, port=8080)
  # I want to continue to execute code here

I don't fully understand how everything is working, am I asking a stupid question?


Solution

  • The problem is as you described it. You do not fully understand how everything works.

    The most important thing that you are missing is that the python-socketio package is not a web server. This package just implements the Socket.IO logic, but you have to add a web server through which your Socket.IO code is available.

    From the code that you included in your question, it appears that you have selected to attach the Socket.IO code to a web application built with the aiohttp framework, and use its own web server. Correct?

    Then the real question that you have is how to run the aiohttp web server in a non-blocking way.

    And it runs out that aiohttp has information on this in their documentation: https://docs.aiohttp.org/en/stable/web_advanced.html#application-runners. The example they have does this:

    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, 'localhost', 8080)
    await site.start()  # <-- starts the server without blocking
    
    # you can do whatever you want here!