I’m trying to implement some simple back and forth communication between my game and a separate process running on my server. I’ve been trying to use StreamPeerTCP but I’m running into a strange issue. One-way communication works without issue, with the following code, I get the expected Received '12345' on my server.
# Godot snippet
func create_session() -> void:
var peer = StreamPeerTCP.new()
peer.connect_to_host("localhost", 6789)
while peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
peer.poll()
peer.put_data("12345".to_ascii_buffer())
# while peer.get_available_bytes() < 5:
# peer.poll()
# var data := peer.get_data(5)
# print(data)
# Python TCP server
async def main():
server = await asyncio.start_server(handle_request, 'localhost', 6789)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.serve_forever()
async def handle_request(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
data = await reader.read()
message = data.decode("ascii")
print(f"Received '{message}'")
# writer.write(b"54321")
# await writer.drain()
# writer.close()
However, when I attempt to send a response back (i.e. uncomment the commented-out lines), the Godot process freezes up, continuously polling and never receiving any data. What’s even more strange is that the Python process never gets the sent data until I forcibly close the Godot process. I’ve tried setting the no-delay mode to true, but that didn’t help.
What am I doing wrong here? Is there a better way to handle this use case? I’m truly at a loss.
Looks like a TCP-level issue - it buffers small messages into larger buffers so it doesn’t have to actually transmit data as often. I think if you were to send data at regular intervals this could soften somewhat to receiving data but with a delay.
I added peer.set_no_delay(true) to the Godot side and server.sockets[0].setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) to the Python side (which seems to be the default for TCP sockets anyway), and the behavior is the same.
From the behaviour you described it sounds like peer.put_data won’t send the data if the main thread is blocked.
Have you already tried polling the peer every frame instead of just blocking the whole main thread?
and it worked. So it seems reader.read() got stuck forever waiting for more data - according to the docs (Streams — Python 3.12.1 documentation) it will wait for EOF.