0

This is a lower level variation of a similar previous question.

The TCP Echo Server example in the Transports and Protocols docs will never timeout an established socket connection. In order to add a 5 seconds timeout, I simply scheduled a callback with a loop.call_later call.

import asyncio


class EchoServerProtocol(asyncio.Protocol):
    def connection_made(self, transport):
        self.transport = transport
        # ---> here the timeout is implemented <---
        self.timer = asyncio.get_running_loop().call_later(5, transport.close)
        print("connection made")

    def data_received(self, data):
        self.timer.cancel()
        self.transport.write(data)
        self.transport.close()
        print("echo sent")

    def connection_lost(self, exc):
        self.timer.cancel()
        print("connection lost")


async def main():
    loop = asyncio.get_running_loop()
    server = await loop.create_server(lambda: EchoServerProtocol(), "127.0.0.1", 8888)
    async with server:
        await server.serve_forever()


asyncio.run(main())

I was wondering if this is can be considered a "canonical" solution, or better methods can be devised.

Stefano M
  • 4,267
  • 2
  • 27
  • 45

1 Answers1

0

You could try to explicitly manage the connection as returned by loop.create_connection() together with the new asyncio.timeout() API introduced in Python3.11.

Louis Lac
  • 5,298
  • 1
  • 21
  • 36
  • Bar monkey patching the python libs, I do not see a method for doing this: I have access only to the object returned by `loop.create_server`. Your suggestion could work for a client program, where you call `loop.create_connection` explicitly. Moreover I would like to have the possibility to _reset_ the timeout when activity on the socket happens, and only timeout idling connections. – Stefano M Dec 07 '22 at 14:10