There is plenty of information and examples when it comes to connecting to one server with multiple clients. But I was wondering is there a way for one client to connect to two servers at the same time? Here is my situation:
I have a python client that brings data from one server, analyzes it and sends an appropriate command to another server. There seems to be less information on this issue, If I may call it.
Here is how I tried approaching the issue. First, I made a socketio.Client
class, which would enable me to create two client instances. It did not work. What am I missing here?:
import socketio
class SocketClient(socketio.Client):
def __init__(self, server_ip):
self.server_ip = server_ip # server's ip address
self.sio = socketio.Client(logger=True)
def connect(self):
self.sio.connect(self.server_ip, namespaces=['/my_namespace'])
@self.sio.event
def connect_error(self, error):
print('connection error=> ', error)
@self.sio.event
def my_event(self, server_response):
# Here I have to take the server_response
# and send it to another server.
# How do I do it?
# self.sio.emit('some_event', server_response)
# that does not work, as I do not have the second client instance
pass
@self.sio.event
def my_other_event(self, server_response):
# process the response
pass
# initiate the two client instances:
if __name__ == '__main__':
first_client = SocketClient('http://192.168.100.103')
second_client = SocketClient('http://192.168.100.104')
first_client.connect()
second_client.connect()
after my first try did not work, I ditched the class-instance approach and went for functional one:
import socketio
first_client = socketio.Client()
second_client = socketio.Client()
@second_client.event
@first_client.event
def connect():
print(f'connected with id {first_client.sid}')
@second_client.event
@first_client.event
def connect_error(e):
print('Error=> ', e)
@second_client.event
@first_client.event
def disconnect():
print('disconnected')
@first_client.event
def my_event(server_response):
# Here I have to take the server_response
# and send it to another server.
second_client.emit('some_event', server_response) # is it even possible?
@second_client.event
def my_other_event(server_response):
# handle the response
pass
if __name__ == '__main__':
first_client.connect('http://192.168.100.103')
second_client.connect('http://192.168.100.104')
In both cases, I am technically creating two clients. I might as well make them into separate files like first_client.py
and second_client.py
.
See where I am going with this? The goal is to get the data from server one, process it and send it to the other server with ideally one client. Please forgive me if I am missing something very obvious here. Any help is much appreciated.
P.S. both servers are up and running without any problem.
I am using NameSpace to solve this problem.
first make a Namespace class
class MyCustomNamespace(socketio.AsyncClientNamespace):
async def on_connect(self):
print("I'm connected!")
async def on_disconnect(self):
print("I'm disconnected!")
async def on_my_event(self, data):
await self.emit('my_response', data)
async def on_message(self, data):
print("[echo]:", data)
class mysio:
def __init__(self) -> None:
global sio
self.sio = socketio.AsyncClient(logger=False, engineio_logger=False)
self.sio.register_namespace(MyCustomNamespace('/')) # bind
then make 2 clients. since wait() will block the process, I use create_task().
async def main():
async def fun1():
sio1 = mysio().sio
await sio1.connect('http://192.168.3.85:11451')
await sio1.emit('message', b'11111110001')
await sio1.wait()
async def fun2():
sio2 = mysio().sio
await sio2.connect('http://localhost:8080')
await sio2.emit('message', 'from sio2')
await sio2.wait()
tasks = [asyncio.create_task(fun1()),asyncio.create_task(fun2()) ]
await asyncio.wait(tasks)
asyncio.run(main())