I’m making a library for adding multiplayer to python games. The library is an extra layer above the websockets library. I’m currently writing a test for it where two squares are controlled by two clients and move on both clients. Whenever the square is moved, I send an update to the server. The first time I do this, it works fine. However, any subsequent sends, and the message just seems to get lost. I get past the websocket.send call at the client but the message doesn’t arrive at the server.
Originally I thought the message wasn’t being handled correctly on the server’s side. However if I keep moving the square around, the websocket times out even though I should be sending loads of messages.
The code to receive the messages:
async for msg_json in websocket:
print("Message received")
msg = loads(msg_json)
self.msg_handler(msg, new_client.id)
print("Message handled")
client.send() is the same as websocket.send() in the websockets library (see above). From what I have read, the clients have a write buffer that messages get put in until sent. I think I am able to change the limit on this buffer however I’m not 100% sure.
As you can see, I print “Sent update” after sending the message so it isn’t getting stuck at that line. I also tried sending back a response after handling the message but that didn’t work either.
You are mixing futures between different loops by using threading. In other words, you create two loops and then pass futures between them. It cannot work that way.
How would I handle incoming messages if I don’t know when they will arrive without blocking the program? I’ve tried using the normal async for msg in websocket but this doesn’t let any code run after this. When I need to draw the screen every frame and handle input etc., I can’t have the program blocked. Thanks!
Run the client in another thread; keep your game in the main thread.
import asyncio
import threading
import websockets
import time
async def websocket_handler():
uri = "ws://localhost:8765"
async with websockets.connect(uri) as websocket:
while True:
await websocket.send(input("Enter message: "))
# Your WebSocket logic here
message = await websocket.recv()
print(f"Received message: {message}")
def start_websocket_thread():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(websocket_handler())
if __name__ == "__main__":
# Create a new thread for the WebSocket client
websocket_thread = threading.Thread(target=start_websocket_thread)
# Start the WebSocket thread
websocket_thread.start()
try:
# Your main application logic can run here
while True:
# Do other tasks in the main thread
print('Ho ho ho')
time.sleep(2.0)
except KeyboardInterrupt:
# Handle keyboard interrupt (Ctrl+C) to gracefully stop the WebSocket thread
pass
finally:
# Stop the WebSocket thread when the main application exits
websocket_thread.join()
Sorry this is late, but I can’t for the life of me figure out how I can interrupt the message loop the send a message. Doesn’t matter what I try, nothing worked. Thanks for the help.
I’m using a async for msg in ws and get this to send a message as soon as I need to. If I have a condition in the loop that checks if a message needs to be sent but this means the message will only be sent when a message is received.
I had similar problem. A websocket has buffer and if the send command does not fill the buffer, the data remains on a client side and not flushed. The solution was to set write_limit=0 (or to make it small).