Python Socket.IO server and client

Overview

python-socketio

Python implementation of the Socket.IO realtime client and server.

Version compatibility

The Socket.IO protocol has been through a number of revisions, and some of these introduced backward incompatible changes, which means that the client and the server must use compatible versions for everything to work.

If you are using the Python client and server, the easiest way to ensure compatibility is to use the same version of this package for the client and the server. If you are using this package with a different client or server, then you must ensure the versions are compatible.

The version compatibility chart below maps versions of this package to versions of the JavaScript reference implementation and the versions of the Socket.IO and Engine.IO protocols.

JavaScript Socket.IO version Socket.IO protocol revision Engine.IO protocol revision python-socketio version
0.9.x 1, 2 1, 2 Not supported
1.x and 2.x 3, 4 3 4.x
3.x 5 4 5.x

Resources

Comments
  • Emit from background thread in python

    Emit from background thread in python

    I have a flask server, which has HTTP routes, and SOCKET routes, and the websocket works fine like this. I can receive and emit events.

    I am using python-socketio so I can get the sid on every request inbound - instead of using Flask-SocketIO.

    I also have a permanently running background thread in the flask server, which does some custom polling, and when it gets data, it needs to emit a message from within the thread, to the sid provided as part of the data that is polled.

    When I try this, it seems as if the socket cannot emit because it is out of context.

    When I was writing this at first, I managed to emit from within a thread, and from HTTP routes, but that was using Flask-SocketIO, which I am trying to avoid, as I need to be able to get the sid from every incoming request as a string.

    Any advice?

    question 
    opened by djpimp2010 57
  • "The client is using an unsupported version of the Socket.IO or Engine.IO protocols"

    I use python flask as server frame React as front use socket.io-client 3.0.4 as client python-socketio 5.0.0 as server but l can not connect always "The client is using an unsupported version of the Socket.IO or Engine.IO protocols"

        const socket = io("ws://127.0.0.1:8888");
        // client-side
        socket.on("connect", () => {
          console.log(socket.id); // x8WIv7-mJelg7on_ALbx
        });
    
    from flask import Flask,abort,jsonify,request
    from dataProcess import handleDataProcess
    import socketio
    import setting 
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    app.config.from_object(setting.DevConfig)
    sio = socketio.Server()
    print({sio})
    app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
    
    
    @app.route('/api/dataprocess',methods=['POST'])
    def dataProcess():
        params = request.json.get('params')
        result = handleDataProcess(params)
        emit.SocketIO('dataprocesssuccess',{'test':11})
        return jsonify(result)
    @sio.event
    def connect():
        print("I'm connected!")
    
    @sio.event
    def connect_error():
        print("The connection failed!")
    
    @sio.event
    def disconnect():
        print("I'm disconnected!")
    @sio.on('my_event')
    def my_event(data):
        print('Received data: ', data)
    if __name__ == '__main__' :  
        app.run(host='127.0.0.1',port = 8888)
    

    i want to konw why who can help me # #

    question 
    opened by kalaersun 52
  • How to reconnect after engineio warning

    How to reconnect after engineio warning

    Every so often, I run into a situation where I get this stacktrace when running a client:

    WARNING:engineio.client:Read loop: WebSocket connection was closed, aborting
    INFO:engineio.client:Waiting for write loop task to end
    INFO:engineio.client:Exiting write loop task
    INFO:engineio.client:Waiting for ping loop task to end
    WARNING:engineio.client:PONG response has not been received, aborting
    INFO:engineio.client:Exiting ping task
    INFO:engineio.client:Exiting read loop task
    

    However, the client never seems to reconnect. Also, there's no exception for me to latch onto (so that I can reconnect, myself).

    How would you recommend handling reconnection in this scenario?

    bug 
    opened by bachya 43
  • Invalid async_mode specified

    Invalid async_mode specified

    hello! Everything was OK when I run my python file, but it raised error run after be packed with pyinstaller:

    Traceback (most recent call last):
    
      File "ems\core\task.py", line 67, in add
      File "ems\ems_socket_service.py", line 26, in __init__
      File "site-packages\socketio\server.py", line 72, in __init__
      File "site-packages\engineio\server.py", line 100, in __init__
    ValueError: Invalid async_mode specified
    

    the code :self.socketio = socketio.Server(async_mode='gevent')

    I tried self.socketio = socketio.Server(), it's also useless, and i have installed gevent.

    question 
    opened by yousiku 41
  • What is the proper way to disconnect a client from the server side?

    What is the proper way to disconnect a client from the server side?

    Greetings, I am trying to disconnect a client from the server side. I use aiohttp with socketio.

    I use:

    class GlobalNamespaceServer(AsyncNamespace):
        # namespace for /
        async def on_disconnect(self, sid: str):
            await self.emit('disconnect', room=sid)
    
        async def on_connect(self, sid, environ):
            # I need to send event 'accessDenied'
            await self.emit('accessDenied', 'smth', room=sid)
            loop.create_task(self.disconnect(sid))
            return True
    

    As far as I know, the problem is here:

                ret = await s.handle_get_request(environ)
                if s.closed:
                    # websocket connection ended, so we are done (socket has already been deleted by `sio.disconnect()`)
                    del self.sockets[sid]
                return ret
    

    in _handle_connect function.

    Logs

    2019-10-23 17:46:33,558 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet OPEN data {'sid': 'e6c6d024dd41435084460bd42ffc93bb', 'upgrades': [], 'pingTimeout': 60000, 'pingInterval': 25000}
    2019-10-23 17:46:33,559 [INFO] socketio.server: emitting event "accessDenied" to e6c6d024dd41435084460bd42ffc93bb [/]
    2019-10-23 17:46:33,560 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 2["accessDenied",{"data":{"code":"notAuthorized","description":"text"},"headers":{}}]
    2019-10-23 17:46:33,561 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 0
    2019-10-23 17:46:33,561 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Received request to upgrade to websocket
    2019-10-23 17:46:33,562 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Upgrade to websocket successful
    2019-10-23 17:46:38,564 [INFO] socketio.server: emitting event "disconnect" to e6c6d024dd41435084460bd42ffc93bb [/]
    2019-10-23 17:46:38,565 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 2["disconnect",null]
    2019-10-23 17:46:38,565 [INFO] socketio.server: Disconnecting e6c6d024dd41435084460bd42ffc93bb [/]
    2019-10-23 17:46:38,565 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 1
    2019-10-23 17:46:38,565 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet CLOSE data None
    2019-10-23 17:46:38,569 [ERROR] aiohttp.server: Error handling request
    Traceback (most recent call last):
      File ".../lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
        resp = await task
      File "...lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
        resp = await handler(request)
      File "...lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 119, in impl
        return await handler(request)
      File "...lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 109, in impl
        return await handler(request)
      File "...lib/python3.7/site-packages/engineio/asyncio_server.py", line 234, in handle_request
        b64, jsonp_index)
      File "...lib/python3.7/site-packages/engineio/asyncio_server.py", line 388, in _handle_connect
        del self.sockets[sid]
    KeyError: 'e6c6d024dd41435084460bd42ffc93bb'
    

    Could you please give me advice, what is the proper way?

    investigate 
    opened by PaulWasTaken 27
  • Is there a test client?

    Is there a test client?

    Hello and thanks for the library!

    I'm using it with Starlette and trying to implement some integration test. Is there a test client for socketio similar to the one they provide for the basic HTTP/websocket (here), or examples about how to implement such a test?

    enhancement 
    opened by jacopofar 25
  • WebSocket upgrade failed

    WebSocket upgrade failed

    I always get this log message when connecting:

    2019-03-06 18:23:16.214 engineio.client           WARNING  WebSocket upgrade failed: no PONG packet
    
    $ pip freeze | grep -e socketio -e engineio -e websocket
    DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
    python-engineio==3.4.3
    python-socketio==3.1.2
    websocket-client==0.55.0
    $ python --version
    Python 2.7.12
    $ 
    
    bug 
    opened by sambrightman 25
  • Emitting events to clients stops working

    Emitting events to clients stops working

    Describe the bug This is a bit of a nasty bug I've been trying to diagnose over the last month or two. I've been desperately trying to come up with reproduction steps, but so far haven't had any luck. What I do have, though, is a great deal of information about the symptoms. I'm hoping you may be able to help point me in the right direction so I can provide more information to you.

    For a bit of context about the application: I have several python-socketio instances deployed that push out events to clients throughout the day. The events are generated from a Django app that utilizes a RedisManager in write_only mode. The python-socketio side is fully async, and uses an AsyncRedisManager. The python-socketio instances are deployed in ASGI mode, running via a UnicornWorker class on gunicorn.

    After a few weeks, I started observing that certain connected clients were not receiving messages. After a bit of diagnosing, I identified that, of the 3 python-socketio instances running, 1 of them was causing the issue. Clients connecting to that instance could connect, emit events (and receive responses), as well as send/receive heartbeat messages, but they were not receiving events emitted from the server itself.

    I initially blamed it on a possible disconnection between that python-socketio instance and redis, but with further diagnostics I was able to see that any calls to emit, even local ones from within the namespace, are not delivered. To illustrate this point, I added this method to my namespace:

    async def on_log(self, sid, msg):
        logger.warn(f'[Message from "{sid}"] {msg}')
        await self.emit(Event.LOG, data=msg, room=sid)
    

    On clients connected to a functioning python-socketio instance, emitting a log received a response from the server as expected: working

    However, on the python-socketio instance experiencing this issue, nothing was sent back to the client.

    I can confirm that the instance did indeed get the event from the client though, because the logger.warn() was being called: Screen Shot 2021-12-02 at 11 36 27 AM

    The thing that is particularly interesting about this is that returning data from an event on the server does still work. When the frontend clients connect, they emit an event which always receives a response from the server. Even when emitting an event to a python-socketio instance with this issue, that always gets delivered. So it seems to specifically be something about the emit process that is breaking down.

    This issue generally starts happening to an instance after a few days. I've seen it happen as soon as 1 day after a container being created, and as long as a few weeks.

    This is everything I can think of right now. If you have any insight at all as to what I could do to further investigate, please let me know. I know this is a difficult ask because there aren't any repro steps, but I'm hoping with your full understanding of the system you may have some ideas. Thank you so much!

    To Reproduce None yet, see above

    Expected behavior Emitted messages should not stop getting delivered.

    Logs I am going to redeploy with additional logging enabled. Nothing was in the normal logs.

    Additional context I'm using uvloop, and I initially thought it could've been an outdated version of it causing issues. I've since upgraded uvloop to 0.16.0 and the issue still happens.

    Full versions are below:

    python-socketio==5.4.1
    aioredis==1.3.1
    hiredis==2.0.0
    websockets==9.1  # Temporarily pinned to 9.1 until the closing issue is fixed (https://github.com/aaugustin/websockets/issues/1072)
    gunicorn==20.1.0
    uvicorn[standard]==0.15.0
    uvloop==0.16.0
    
    question 
    opened by lsapan 24
  • How to add connection to the database(PostgreSQL)

    How to add connection to the database(PostgreSQL)

    I try add connection to the DB in my app.

    # -*- coding: utf-8 -*-
    import asyncio
    import base64
    import gzip
    import hashlib
    import pathlib
    
    import aiofiles
    import socketio
    from aiohttp import web
    
    from models import setup_pg
    from settings import logger, options
    from utils import load_config
    
    PROJ_ROOT = pathlib.Path(__file__).parent.parent
    TEMPLATES_ROOT = pathlib.Path(__file__).parent / 'templates'
    
    global sio
    
    async def index(request):
        """
        Simple client in web browser
        :param request: request from page
        :return: response app.html file
        """
        with open(str(PROJ_ROOT / 'templates' / 'app.html')) as f:
            return web.Response(text=f.read(), content_type='text/html')
    
    
    @sio.on('my event', namespace='/test')
    async def test_message(sid, message):
        """
        Custom event handler with event_name and
        Socket.IO namespace for the event. This handler works like echo-server.
        :param sid: Session ID of the client
        :param message: message payload
        :return: None
        """
        # Added transport mode checker
        transport_mode = sio.transport(sid)
        logger.debug('MESSAGE TRANSPORT MODE (%s): %s' % (sid, transport_mode))
        try:
            if isinstance(message, dict):
                await sio.emit('my response',
                               {'data': message.get('data', 'Message should be dict: {"data": "some text"}')},
                               room=sid, namespace='/test')
                logger.debug('event: "my event"(ECHO), SID: %s Message: %s' % (sid, message))
            else:
                raise TypeError('Message should be dict: {"data": "some text"}')
        except ValueError as e:
            logger.error('Handle ERROR: %s' % e)
        except TypeError as e1:
            logger.error('Handle ERROR: %s' % e1)
    
    
    def call_back_from_client(*args, **kwargs):
        """
        Handle callback from client with any parameters
        :param args: positional arguments
        :param kwargs: named arguments
        :return: none
        """
    
        for arg in args:
            logger.debug('My EVENT(FILE CALLBACK - args) %s' % arg)
    
        for key, value in kwargs:
            logger.debug('My EVENT(FILE CALLBACK - kwargs) %s:%s' % (key, value))
    
    
    @sio.on('file', namespace='/test')
    async def test_binary_message(sid):
        """
        Custom event handler with event_name and
        Socket.IO namespace for the event. This handler send
        image file in base64 gzip.
        :param sid: Session ID of the client
        :return: emit file base64 gzip
        """
        content_b64 = ''
        hash_sum = ''
        try:
            async with aiofiles.open('static/test.png', mode='rb') as image_file:
                content = await image_file.read()
                gzip_file = gzip.compress(content)
                content_b64 = base64.b64encode(gzip_file)
                hash_sum = hashlib.md5(content_b64).hexdigest()
        except OSError as e:
            logger.error('Handle ERROR: %s' % e)
        await sio.emit('file response',
                       {'data': content_b64.decode('utf-8'), 'hash_sum': hash_sum},
                       room=sid,
                       namespace='/test',
                       callback=call_back_from_client)
        logger.debug('My EVENT(FILE) (%s): %s' % (sid, content_b64[:20]))
        del content_b64
    
    
    @sio.on('message received', namespace='/test')
    async def test_message(sid, message):
        logger.debug('My EVENT(CALL BACK) (%s): %s' % (sid, message))
        return True
    
    
    @sio.on('my broadcast event', namespace='/test')
    async def broadcast_message(sid, message):
        await sio.emit('my response', {'data': message['data']}, namespace='/test')
        logger.debug('BROADCAST MESSAGE(%s): %s' % (sid, message))
    
    
    @sio.on('join', namespace='/test')
    async def join(sid, message):
        sio.enter_room(sid, message['room'], namespace='/test')
        await sio.emit('my response', {'data': 'Entered room: ' + message['room']},
                       room=sid, namespace='/test')
        logger.debug('JOIN ROOM (%s): %s' % (sid, message))
    
    
    @sio.on('leave', namespace='/test')
    async def leave(sid, message):
        sio.leave_room(sid, message['room'], namespace='/test')
        await sio.emit('my response', {'data': 'Left room: ' + message['room']},
                       room=sid, namespace='/test')
        logger.debug('LEAVE ROOM (%s): %s' % (sid, message))
    
    
    @sio.on('close room', namespace='/test')
    async def close(sid, message):
        await sio.emit('my response', {'data': 'Room %s is closing' % message['room']},
                       room=message['room'], namespace='/test')
        await sio.close_room(message['room'], namespace='/test')
        logger.debug('CLOSE ROOM (%s): %s' % (sid, message))
    
    
    @sio.on('my room event', namespace='/test')
    async def send_room_message(sid, message):
        # Added transport mode checker
        # transport_mode = sio.transport(sid)
        # logger.debug('TRANSPORT MODE(%s): %s' % (sid, transport_mode))
    
        await sio.emit('my response', {'data': message['data']},
                       room=message['room'], namespace='/test')
        logger.debug('ROOM EVENT (%s): %s' % (sid, message))
    
    
    @sio.on('disconnect request', namespace='/test')
    async def disconnect_request(sid):
        await sio.disconnect(sid, namespace='/test')
        logger.debug('DISCONNECT REQUEST: %s' % sid)
    
    
    @sio.on('connect', namespace='/test')
    async def test_connect(sid, environ):
        # Added transport mode checker
        transport_mode = sio.transport(sid)
        logger.debug('CONNECT TRANSPORT MODE (%s): %s' % (sid, transport_mode))
    
        await sio.emit('my response', {'data': 'Connected', 'count': 0},
                       room=sid, namespace='/test')
        logger.debug('CONNECT USER: %s, ENVIRON: %s' % (sid, environ))
    
    
    @sio.on('disconnect', namespace='/test')
    def test_disconnect(sid):
        logger.debug('DISCONNECT USER: %s' % sid)
    
    async def init(loop):
        # load config from yaml file
        conf = load_config(str(PROJ_ROOT / 'config' / 'dev.yml'))
    
        # setup application and extensions
        sio = socketio.AsyncServer(async_mode='aiohttp',
                                   allow_upgrades=True)
        app = web.Application(loop=loop)
        sio.attach(app)
        pg = await setup_pg(app, conf, loop)
    
        # setup views and routes
        app.router.add_static('/static', path=str(PROJ_ROOT / 'static'))
        app.router.add_get('/', index)
        return app
    
    
    def main():
    
        # Run background task
        # sio.start_background_task(background_task)
        loop = asyncio.get_event_loop()
        app = loop.run_until_complete(init(loop))
        # Run app
        web.run_app(app, host=options.host, path=options.path, port=options.port)
    
    
    if __name__ == '__main__':
    
        main()
    

    I use global for sio, but I have this ERROR. Traceback (most recent call last): File "simple_chat.py", line 31, in <module> @sio.on('my event', namespace='/test') NameError: name 'sio' is not defined Is this a correct way of DB connection?

    opened by MaxOvcharov 23
  • Not emitting from callback

    Not emitting from callback

    Hello,

    I try to create a socketio server with a binance websocket server.

    The binance websocket server fire a callback every 5seconds or so. (Line 30 ) in my code => #1 The callback is fire from another thread created by the binance websocket.

    ( Line 22 ) in my code => #2 It doesn't work when i try to emit from the callback.

    ( Line 16 ) in my code => #3 But when i emit from the main thread it works.

    I made my code as simple as possible to understand.

    Do you have an idea what i'm doing wrong ?

    import socketio
    import eventlet
    import eventlet.wsgi
    from flask import Flask, render_template
    from binance.websockets import BinanceSocketManager
    from binance.client import Client
    from binance.enums import *
    
    sio = socketio.Server(logger=False, engineio_logger=False)
    app = Flask(__name__)
    
    @sio.on('connect')
    def connect(sid, environ):
        sio.enter_room(sid, "room_test")
        # IS EMITING. OK  <========================================================== #3
        sio.emit("markets", ["CONNECT"], room="room_test", namespace="/")
    
    
    def callback(msg):
        print("msg : ",msg["s"])
        # NOT EMITING. CLIENT RECEIVE NOTHING  <===================================== #2
        sio.emit("markets", ["CALLBACK"], room="room_test", namespace="/")
    
    if __name__ == '__main__':
    
        client = Client("key",
                        "apikey")
    
        # The binance websocket start in another thread <============================ #1
        bm = BinanceSocketManager(client)
        bm.start_kline_socket('BNBBTC', callback, interval=KLINE_INTERVAL_1MINUTE)
        bm.start()
    
        app = socketio.Middleware(sio, app)
        eventlet.wsgi.server(eventlet.listen(('', 8060)), app)
    
    question 
    opened by ghost 22
  • Class-based namespaces

    Class-based namespaces

    Hi,

    I've implemented namespace-based grouping of event handlers into classes as a little enhancement to the Server.on(...) method which is currently the only available way to register event handlers. As this can become muddled rather quickly I wrote this extension. It also cares about setting default namespaces when calling emit, disconnect etc. on such a Namespace object.

    Tests and docs are updated as well.

    Hope it gets merged and will help some people writing their Socket.IO apps more easily.

    enhancement 
    opened by bob1de 21
  • BadNamespaceError / is not a connected namespace

    BadNamespaceError / is not a connected namespace

    Describe the bug Sometimes it comes back to me

    File "/usr/local/lib/python3.10/dist-packages/socketio/client.py", line 393, in emit   
    socketio.exceptions.BadNamespaceError / is not a connected namespace
    

    To Reproduce I've been trying various ways

    First attempt:

    sio = socketio.Client(logger=False,ssl_verify=False,reconnection=True)
    sio.connect('https://domain:3001' ,transports="polling")
    sio.emit('debug', {'room': 'hi','msg':'Hi mate'}) #works
    sio.sleep(5)
    sio.emit('debug', {'room': 'hi','msg':'Hi again'}) #works again
    
    ... other tasks ...
    
    sio.emit('debug', {'room': 'hi','msg':'Tasks finish'}) #error
    

    Second attempt:

    sio = socketio.Client(logger=False,ssl_verify=False,reconnection=True)
    sio.connect('https://domain:3001' ,transports="polling")
    sio.emit('debug', {'room': 'hi','msg':'Hi mate'}) #works
    sio.sleep(5)
    sio.start_background_task(task(),123) #task() solves multiple tasks
    sio.wait()
    

    Expected behavior Send message at the end of a long task

    Logs

    Sending packet MESSAGE data 2["debug",{"room":"hi","msg":"Hi again"}]
    Received packet PING data 
    Sending packet PONG data 
    Sending polling GET request to https://domain:3001/socket.io/?transport=polling&EIO=4&sid=m_JKfkEHmf3Apu_8AAAU
    Received packet CLOSE data 
    Sending packet CLOSE data None
    disconnected from server
    Waiting for write loop task to end
    Unexpected status code 400 in server response, aborting
    Exiting write loop task
    Exiting read loop task
    
    opened by nouser000 4
  • docs: please make sticky sessions requirement louder

    docs: please make sticky sessions requirement louder

    Is your feature request related to a problem? Please describe. When run as a cluster, this library requires sticky sessions to be enabled. This wasn't obvious at first and so I deployed a buggy cluster.

    Please improve the docs or errors to make this requirement clearer (and I'm happy to submit a docs / error message PR, if helpful).

    (Also thank for for providing this library -- I am very happy to be able to run my socketio backend in my existing fastapi stack).

    Describe the solution you'd like In the codebase:

    • remove the sticky sessions requirement if possible (I don't understand the internals of this project or the socketio protocol, but I assume the sticky sessions requirement is in here for a legit reason, and removing it would be a large project if possible)
    • explain the situation in the error message, if possible. In my case the error is usually 'Invalid session', presumably from 2 places in handle_request

    In docs: In the using a message queue section, can you link to the scalability notes warning (which says to use sticky sessions), and make it clear your cluster will fail if you don't meet the reqs?

    Describe alternatives you've considered The alternative I tried first was having my chat intermittently fail in prod. Because my cluster is small, it usually connected eventually, so for a while I assumed it was an error in the ordering of my authorization logic + socket connection.

    Logs n/a, but let me know if you want me to capture something

    Additional context Did a readthrough of other issues mentioning this:

    • #371 'invalid session' with sanic in multiple workers mode
    • #437, #219
    documentation 
    opened by abe-winter 4
  • keep trying to reconnect

    keep trying to reconnect

    Describe the bug Analyze the log of PING pong, the connection has been successful, but it is constantly trying to reconnect, check the traceback, socketio.exceptions.ConnectionError: Already connected

    To Reproduce

    Please fill the following code example:

    Socket.IO server version: 4.1.z

    Server

    const { setupWorker } = require("@socket.io/sticky");
    const crypto = require("crypto");
    const randomId = () => crypto.randomBytes(8).toString("hex");
    
    const { RedisSessionStore } = require("./sessionStore");
    const sessionStore = new RedisSessionStore(redisClient, redisClient1);
    
    const { RedisMessageStore } = require("./messageStore");
    const messageStore = new RedisMessageStore(redisClient);
    
    io.use(async (socket, next) => {
      const sessionID = socket.handshake.auth.sessionID;
      if (sessionID) {
        const session = await sessionStore.findSession(sessionID);
        if (session) {
          socket.sessionID = sessionID;
          socket.userID = session.userID;
          socket.username = session.username;
          return next();
        }
      }
      
      const auth_info = socket.handshake.auth.auth_info;
      if (auth_info == 'admin'){
        socket.userID = -1 
        socket.username = 'admin';
        socket.room_code = 'admin_-1'
        return next();
      }
      console.log(auth_info,33, auth_info == 'admin')
      if (!auth_info) {
        return next(new Error("invalid auth_info"));
      }
      socket.sessionID = randomId();
      // socket.userID = randomId();
    
     user_info = await sessionStore.findUserIdForToken(auth_info);
     console.log(user_info, auth_info)
      if (!user_info){
        console.log(64)
        return next(new Error("invalid auth_info not found"));
      }
      const [uid, source] = user_info
      socket.userID = uid 
      socket.username = source;
      socket.room_code = source + '_' + uid
      next();
    });
    
    io.on("connection", async (socket) => {
      // persist session
      sessionStore.saveSession(socket.sessionID, {
        userID: socket.userID,
        username: socket.username,
        connected: true,
      });
    
    

    Socket.IO client version: python-socketio 5.7.2

    Client

    import socketio
    
    sio = socketio.Client(logger=True, engineio_logger=True)
    
    
    @sio.event
    def connect():
        print('连接成功')
    
    @sio.event
    def connect_error(data):
        print(14, data)
        # exit()
    @sio.event
    def disconnect():
        print('断开连接了')
    
    @sio.on('private message')
    def private_message(data):
        print(22, data)
    
    @sio.event
    def hello(a, b, c):
        print(a, b, c)
    
    @sio.on('*')
    def catch_all(event, data):
        print(11, event,data, 28)
    
    
    if __name__ == '__main__':
        sio.connect('https://ws.xxxx.com', auth={'auth_info': 'admin'}, wait_timeout=10)
        sio.emit('private message', {'body': '1213123', 'to': 'cx_67506'})
        sio.wait()
    

    code

        def _handle_reconnect(self):
            if self._reconnect_abort is None:  # pragma: no cover
                self._reconnect_abort = self.eio.create_event()
            self._reconnect_abort.clear()
            reconnecting_clients.append(self)
            attempt_count = 0
            current_delay = self.reconnection_delay
            while True:
                delay = current_delay
                current_delay *= 2
                if delay > self.reconnection_delay_max:
                    delay = self.reconnection_delay_max
                delay += self.randomization_factor * (2 * random.random() - 1)
                self.logger.info(
                    'Connection failed, new attempt in {:.02f} seconds'.format(
                        delay))
                if self._reconnect_abort.wait(delay):
                    self.logger.info('Reconnect task aborted')
                    break
                attempt_count += 1
                try:
                    self.connect(self.connection_url,
                                 headers=self.connection_headers,
                                 auth=self.connection_auth,
                                 transports=self.connection_transports,
                                 namespaces=self.connection_namespaces,
                                 socketio_path=self.socketio_path)
                except (exceptions.ConnectionError, ValueError):
                    # traceback.print_exc()
                    pass
                else:
                    self.logger.info('Reconnection successful')
                    self._reconnect_task = None
                    break
                if self.reconnection_attempts and \
                        attempt_count >= self.reconnection_attempts:
                    self.logger.info(
                        'Maximum reconnection attempts reached, giving up')
                    break
            reconnecting_clients.remove(self)
    

    log Connection failed, new attempt in 5.49 seconds Traceback (most recent call last): File "/Users/dai/Dev/aiguo_python/ven3a-socketio/lib/python3.10/site-packages/socketio/client.py", line 661, in _handle_reconnect self.connect(self.connection_url, File "/Users/dai/Dev/aiguo_python/ven3a-socketio/lib/python3.10/site-packages/socketio/client.py", line 307, in connect raise exceptions.ConnectionError('Already connected') socketio.exceptions.ConnectionError: Already connected Connection failed, new attempt in 5.21 seconds Traceback (most recent call last): File "/Users/dai/Dev/aiguo_python/ven3a-socketio/lib/python3.10/site-packages/socketio/client.py", line 661, in _handle_reconnect self.connect(self.connection_url, File "/Users/dai/Dev/aiguo_python/ven3a-socketio/lib/python3.10/site-packages/socketio/client.py", line 307, in connect raise exceptions.ConnectionError('Already connected') socketio.exceptions.ConnectionError: Already connected Connection failed, new attempt in 5.34 seconds Traceback (most recent call last): File "/Users/dai/Dev/aiguo_python/ven3a-socketio/lib/python3.10/site-packages/socketio/client.py", line 661, in _handle_reconnect self.connect(self.connection_url, File "/Users/dai/Dev/aiguo_python/ven3a-socketio/lib/python3.10/site-packages/socketio/client.py", line 307, in connect raise exceptions.ConnectionError('Already connected') socketio.exceptions.ConnectionError: Already connected

    log2

    WebSocket upgrade was successful
    Received packet MESSAGE data 0{"sid":"gvr4xtgkcIBMFnAzAAAP"}
    Namespace / is connected
    连接成功
    Reconnection successful
    Reconnection successful
    Connection failed, new attempt in 4.22 seconds
    Connection failed, new attempt in 4.12 seconds
    Connection failed, new attempt in 5.02 seconds
    Connection failed, new attempt in 5.34 seconds
    Connection failed, new attempt in 5.02 seconds
    Connection failed, new attempt in 5.21 seconds
    Connection failed, new attempt in 4.81 seconds
    Connection failed, new attempt in 5.21 seconds
    Connection failed, new attempt in 4.70 seconds
    Connection failed, new attempt in 5.24 seconds
    Connection failed, new attempt in 5.39 seconds
    Received packet PING data 
    Sending packet PONG data 
    Connection failed, new attempt in 5.17 seconds
    Connection failed, new attempt in 5.15 seconds
    Connection failed, new attempt in 5.46 seconds
    Connection failed, new attempt in 5.06 seconds
    Connection failed, new attempt in 4.51 seconds
    Connection failed, new attempt in 4.81 seconds
    Connection failed, new attempt in 5.16 seconds
    

    Platform:

    • client
      • Device: mac pro
      • OS: macos
    • server
      • Device: pc
      • OS: ubuntu20.04

    Additional context Add any other context about the problem here.

    question 
    opened by dly667 8
  • How to shorten 10 second timeout for .connect()

    How to shorten 10 second timeout for .connect()

    Describe the bug When my python code tries to connect to my socket-io server but the server is not running, it takes 10 full seconds before the .connect() function times out. Using the code snippet shown below, the connect function starts at 01:18:02 and times out at 01:18:12.

    [2022-10-19 01:18:02.304] (/code/lib/src/cr/lib/connections.py:connections:get_socketio_client) - INFO - cr.lib - Connecting to socket-io server http://socket_io:3000 [2022-10-19 01:18:12.321] (/code/lib/src/cr/lib/connections.py:connections:get_socketio_client) - WARNING - cr.lib - Connection to socket-io server http://socket_io:3000 failed

    To Reproduce Steps to reproduce the behavior:

          import socketio
          SOCKETIO_SSL_VERIFY = False
    
            # the request timeout does nothing to stop library from waiting for 10 seconds before connection times out
            # I have not found any way to shorten the timeout.
            _socketio_client = socketio.Client(ssl_verify=SOCKETIO_SSL_VERIFY, request_timeout=1)
    
            auth = {"Authorization": "xxxx"}
            try:
                log.info("Connecting to socket-io server {}".format(SOCKETIO_URI))
                _socketio_client.connect(url=SOCKETIO_URI, auth=auth, wait_timeout=1)
            except socketio.exceptions.ConnectionError:
                # cannot connect to socket server
                message = "Connection to socket-io server {} failed".format(
                    SOCKETIO_URI
                )
                log.warning(message)
                _socketio_client = None
    

    Expected behavior When the socket server is not running or cannot be found, I would expect the connect function to time out almost immediately, within 1 second, or within some other user-defined timeout period.

    Logs See above

    Additional context After I start the socket-io server and retry, the connection gets established immediately. The problem is only when the target socket-io server is not running or otherwise not responding.

    question 
    opened by dcarr178 1
  • option for KeyboardInterrupt to not cause disconnect

    option for KeyboardInterrupt to not cause disconnect

    It appears that I cannot write an application that does its own thing with KeyboardInterrupt, as the underlying engineio client interprets this as a disconnect. There is no option when creating a client to tell it to ignore KeyboardInterrupt. Thoughts?

    question 
    opened by TodAmon 3
Owner
Miguel Grinberg
Miguel Grinberg
Socket.IO integration for Flask applications.

Flask-SocketIO Socket.IO integration for Flask applications. Installation You can install this package as usual with pip: pip install flask-socketio

Miguel Grinberg 4.9k Jan 3, 2023
This websocket program is for data transmission between server and client. Data transmission is for Federated Learning in Edge computing environment.

websocket-for-data-transmission This websocket program is for data transmission between server and client. Data transmission is for Federated Learning

null 9 Jul 19, 2022
Synci - Learning project to create a websocket based client server messaging application

Synci Learning project to create a websocket based client server messaging appli

null 2 Jan 13, 2022
WebSocket client for Python

websocket-client The websocket-client module is a WebSocket client for Python. It provides access to low level APIs for WebSockets. All APIs are for s

null 3.1k Jan 2, 2023
A websocket client for Source Filmmaker intended to trasmit scene and frame data to other applications.

SFM SOCK A websocket client for Source Filmmaker intended to trasmit scene and frame data to other applications. This software can be used to transmit

KiwifruitDev 2 Jan 8, 2022
Websockify is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service. Implementations in Python, C, Node.js and Ruby.

websockify: WebSockets support for any application/server websockify was formerly named wsproxy and was part of the noVNC project. At the most basic l

noVNC 3.3k Jan 3, 2023
WebSocket emulation - Python server

SockJS-tornado server SockJS-tornado is a Python server side counterpart of SockJS-client browser library running on top of Tornado framework. Simplif

Serge S. Koval 854 Nov 19, 2022
Django Channels HTTP/WebSocket server

daphne Daphne is a HTTP, HTTP2 and WebSocket protocol server for ASGI and ASGI-HTTP, developed to power Django Channels. It supports automatic negotia

Django 1.9k Dec 31, 2022
tiny multi-threaded socks4 server implemented in python2

tiny, multi-threaded socks4a server implemented in python2.

null 4 Sep 21, 2022
Benchmark a WebSocket server's message throughput ⌛

?? WebSocket Benchmarker ⌚ Message throughput is how fast a WebSocket server can parse and respond to a message. Some people consider this to be a goo

Andrew Healey 24 Nov 17, 2022
image stream publish server over websocket

Image Stream Push Server 简介 通过浏览器网页实时查看图像处理结果。 环境 运行程序需要安装一下python依赖: tornado: 用于创建http及websocket服务; opencv-contrib-python: 用于图像数据源获取及图像处理。 使用 进入到src目

MrError404 1 Nov 4, 2021
WebSocket and WAMP in Python for Twisted and asyncio

Autobahn|Python WebSocket & WAMP for Python on Twisted and asyncio. Quick Links: Source Code - Documentation - WebSocket Examples - WAMP Examples Comm

Crossbar.io 2.4k Jan 4, 2023
WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws.

ws WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws. Basic usage. server.py import ws server = w

AceExpert 7 Jun 27, 2022
Library for building WebSocket servers and clients in Python

What is websockets? websockets is a library for building WebSocket servers and clients in Python with a focus on correctness and simplicity. Built on

Aymeric Augustin 4.3k Jan 4, 2023
一款为 go-cqhttp 的正向 WebSocket 设计的 Python SDK

Nakuru Project 一款为 go-cqhttp 的正向 WebSocket 设计的 Python SDK 在 kuriyama 的基础上改动 项目名来源于藍月なくる,图标由せら绘制 食用方法 将 nakuru 文件夹移至 Python 的 Lib/site-packages 目录下。

null 35 Dec 21, 2022
Using python-binance to provide websocket data to freqtrade

The goal of this project is to provide an alternative way to get realtime data from Binance and use it in freqtrade despite the exchange used. It also uses talipp for computing

null 58 Jan 1, 2023
alien.py - Python interface to websocket endpoint of ALICE Grid Services

alien.py - Python interface to websocket endpoint of ALICE Grid Services Quick containerized testing: singularity

Adrian Sevcenco 6 Dec 14, 2022
Whatsapp Clone using django, django-channels and websocket

whatsapp-clone Whatsapp Clone using django, django-channels and websocket Features : Signup/Login One on One personal chat with other user Some screen

Anshu Pal 14 Dec 25, 2022
Library for easily creating and managing websockets.

Documentation coming in version 0.1.4 GitHub PyPI Discord Features Easy to use with object oriented syntax. Intellisense support with typehints and do

ZeroIntensity 0 Aug 27, 2022