Twisted and Websockets: Beyond Echo

jMyles picture jMyles · Dec 10, 2010 · Viewed 8k times · Source

In my ongoing curiosity about websockets, I'm noticing a trend:

The "hello world" of the websocket universe, at least at the moment, seems to be "echo" functionality. That is, the demonstrated application is typically, "I send something, I receive something."

While aptly demonstrating that the protocol is functional, this example only actually demonstrates the same type of communication that the traditional request / response cycle enables.

For example, the only demonstration (on the server side) that I can find of twisted.web.websockets is the following:

import sys
from twisted.python import log
from twisted.internet import reactor
from twisted.web.static import File
from twisted.web.websocket import WebSocketHandler, WebSocketSite


class Echohandler(WebSocketHandler):

    def frameReceived(self, frame):
        log.msg("Received frame '%s'" % frame)
        self.transport.write(frame + "\n")


def main():
    log.startLogging(sys.stdout)
    root = File(".")
    site = WebSocketSite(root)
    site.addHandler("/ws/echo", Echohandler)
    reactor.listenTCP(8080, site)
    reactor.run()


if __name__ == "__main__":
    main()

How can I instead examine "push" capability here? ie, how I can leave the web socket open, and then later, at some time determined by the occurrence of some event, send a message through the websocket, the content of which is also influenced by this event?

(Those interested by this question might also regard as compelling this question that I asked a few days ago: Making moves w/ websockets and python / django ( / twisted? ))

Answer

Jerub picture Jerub · Dec 10, 2010

This is an example of an updated EchoHandler that will instead of just being reactive, be proactive.

class ChattyHandler(WebSocketHandler):
    def connectionMade(self):
        self.transport.write('oh hai\n')
        self.saysomething()

    def saysomething(self):
        self.transport.write('still there?\n')
        reactor.callLater(5, self.saysomething)

Unfortunately, websockets from https://github.com/rlotun/txWebSocket/ doesn't seem to have the connectionMade() method, and instead the only thing you can hook into is the __init__. usually you would just override connectionMade() if it were a 'normal' twisted protocol. --Fixed in upstream