skip to Main Content

I’m currently working on a Socket.IO implementation using Python with socketio and eventlet for my server and socketio for my client. Despite successful connections between the client and server, I’m facing an issue where the data sent from the server is not being received/displayed in the client’s console.

Here’s a simplified version of my server (server.py):

import socketio
import eventlet
from threading import Thread
import redis
import time

sio = socketio.Server()
app = socketio.WSGIApp(sio)

redis_conn = None


def initialize_redis_conn():
    global redis_conn
    if redis_conn is None:
        redis_conn = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)
        print("redis connection init")


def insert_update_sid(sid, unique_id):
    """
    Inserts or updates the sid and uniqueId of the client into the Redis cache.
    """
    initialize_redis_conn()
    key = f"DATA_KEY_{unique_id}"
    expiry_in_seconds = 1800
    redis_conn.setex(key, expiry_in_seconds, sid)
    print("Data inserted into Redis successfully")


def get_sid_by_unique_id(unique_id):
    """
    Returns the sessionId (sid) of a client using the uniqueId.
    """
    initialize_redis_conn()
    print("fetching sid")
    key = f"DATA_KEY_{unique_id}"
    sid = redis_conn.get(key)
    if sid:
        print(f"Got sid {sid} using uid {unique_id}")
        return sid
    else:
        return None


def listen_sqs_queue():
    """
    this func is just to mimic the sqs, when sqs receives the message it should send that to client 
    """

    data = {
        "communicationStatus": "OKAY",
        "status": "Complete"
    }
    unique_id = "123789"
    if unique_id:
        print("inside sqs impl is : ", unique_id)
        sid = get_sid_by_unique_id(unique_id=unique_id)
        if sid:
            print("calling send response to client")
            send_response_to_client(sid, data)
            print(
                f"Response has been sent to the client with sessionId: {sid} and uniqueId : {unique_id}")
        else:
            print(f"Client not found for the given uniqueId: {unique_id}")


def send_response_to_client(sid, resp):
    """
    this func sends the response to the client
    """

    sio.emit('response_from_server', f'response : {resp}')
    print("data sent to client ")


@sio.event
def connect(sid, environ):

    print(f"client {sid} connected")
    print("sid type is: ", type(sid))
    token = environ.get('HTTP_TOKEN')
    sio.emit("acknowledge", "ack recevied from server", room=sid)
    if token:
        auth_status_code = 200
        if auth_status_code == 200:
            unique_id = "123789"
            # insert the sid and uniqueId into redis cache 
            insert_update_sid(sid, unique_id)


@sio.event
def disconnect(sid):
    """
    this is a disconnect event which disconnects the client from server
    """
    print(f"client {sid} disconnected")


def start_server():
    initialize_redis_conn()

    # Start the server in a separate thread
    # eventlet.wsgi.server(eventlet.listen(('0.0.0.0', 5000)), app)


    sqs_listen_thread = Thread(target=listen_sqs_queue)
    sqs_listen_thread.start()

    server_thread = Thread(target=eventlet.wsgi.server(eventlet.listen(('localhost', 5000)), app))
    server_thread.start()


    sqs_listen_thread.join()
    server_thread.join()


if __name__ == '__main__':
    start_server()

And my client (client.py):


import requests
import socketio

PORT = "5000"

IP = "localhost"

sio = socketio.Client()


@sio.event
def connect():
    print("connection established to server connect event")


@sio.event
def disconnect():
    print("client disconnected from server")


@sio.event
def server_response(response):
    print("response from server recived")
    print(f"response received from server: {response}")


@sio.event
def acknowledge(ack):
    print(ack)


if __name__ == '__main__':
    data = {}
    stage = "dev"
    token = get_token(stage)
    token = "Radom_token"
    if token:
        print("Token has been generated.")

        url = f"http://{IP}:{PORT}"

        # sio.connect(url, transports=['websocket', 'polling'], headers={'token': token})
        sio.connect(url=url)
        sio.wait()

    else:
        print("Token has not been generated ")

I have verified that both the server and client are successfully connected, but the response_from_server event is not triggered on the client side. I suspect there might be an issue with how I’m emitting events or with the threading setup.

Any insights or suggestions on how to troubleshoot and resolve this issue would be greatly appreciated. Thank you!

2

Answers


  1. You are mixing threads with eventlet. Eventlet is a single-threaded asynchronous platform, you have to stay in the main thread for things to work.

    A relatively simple solution you have is to monkey-patch the Python standard library so that many threading/networking calls are replaced with greenlet-friendly equivalents. You will need this not only for your background thread, but also to make Redis work under eventlet.

    Login or Signup to reply.
  2. Instead of using threads use eventlet.spawn that will work
    in server.py

    def start_server():
       eventlet.spawn(run_sqs)
       eventlet.spawn(eventlet.wsgi.server(eventlet.listen(('0.0.0.0', 5000)), app))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search