lvh / async-pep

Draft PEP for asynchronous IO
ISC License
62 stars 7 forks source link

Example of an Async API compatible protocol #21

Open lvh opened 13 years ago

lvh commented 13 years ago

Needs to use:

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

lvh commented 13 years ago

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

jerub commented 13 years ago

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

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

lvh commented 13 years ago

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

glyph commented 12 years ago

NetstringReceiver in the stdlib would be even better.

nikipore commented 11 years ago

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 commented 11 years ago

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())