async-pep icon indicating copy to clipboard operation
async-pep copied to clipboard

Example of an Async API compatible protocol

Open lvh opened this issue 13 years ago • 6 comments

Needs to use:

  • two-way communication
  • consumers and producers
  • nothing outside the stdlib

This should then ideally work on the stdlib implementation of the Async API backend, of course.

lvh avatar Jun 23 '11 13:06 lvh

I'm thinking about using JSONRPC as the reference protocol here. Motivation:

  • It's fairly simple
  • You can speak it over raw TCP
  • It can be composed with a decent HTTP protocol implementation later
  • It has two-way communication
  • It's easy to do using the tools that are available in the standard library anyway (mostly the json module)
  • It's actually useful and not in the standard library already
  • XMLRPC is in the standard library already

lvh avatar Jun 24 '11 10:06 lvh

I like a line based (\r\n terminated) chat server better because you can quite easily demonstrate essential facets:

  • communication between protocol objects.
  • connection made and connection lost events are needed in chat server (unlike in jsonrpc)
  • can be interfaced with from 'telnet' to localhost - no one has a jsonrpc client with which to exercise their server.
  • is actually a generalisation of an echo server, which is the basic starting point of most socket examples.

Examples used in core python socket module is here: https://babbledrive.appspot.com/static/doc/python-2.7.1/library/socket.html#example

jerub avatar Jun 24 '11 10:06 jerub

Okay. That's a good argument. I like the idea of having LineReceiver in the stdlib because it's so useful.

lvh avatar Jun 24 '11 12:06 lvh

NetstringReceiver in the stdlib would be even better.

glyph avatar Oct 13 '12 05:10 glyph

I'd vote for ChunkReceiver which is already in the PEP (and covers LineReceiver) plus Twisted's ProcessProtocol. I am not 100% sure whether I've got the user story in #25 right, but it seems to me that ProcessProtocol would cover it.

nikipore avatar Mar 12 '13 19:03 nikipore

I actually prefer a generic FrameProtocol over ChunkReceiver (which is a special case of it). I more or less use it in a Twisted context as follows (I show both Twisted-style protocol interface methods and callbacks to ease comparison; personally, I prefer handing over callbacks to subclassing):

class FrameProtocol(Protocol):
    def __init__(self, parser, onFrame, onConnectionLost):
        self._parser = parser
        self._onFrame = onFrame
        self._onConnectionLost = onConnectionLost

    def connectionLost(self, reason):
        self._onConnectionLost(reason)

    def dataReceived(self, data):
        self._parser.add(data)
        for frame in iter(self._parser.get, self._parser.sentinel):
            self.frameReceived(frame)

    def frameReceived(self, frame):
        self._onFrame(frame)

    def send(self, frame):
        self.transport.write(frame.compile())

nikipore avatar Mar 13 '13 06:03 nikipore