Question

I created a server with a custom protocol using Twisted and I have clients that connect to the server on a specific port (say port 1234). I am looking to create a control interface for the server based on a web page of some sort. My research so far indicated Nevow is popular choice but I only need something very simple.

Say for example, every time a browser accesses the hello world page on port 8080, I send a message to clients connected on 1234.

I am a bit confused as to how I can connect these 2 together. I assume I would need to call Server.message from HelloResource.render_GET ?

from twisted.internet import protocol, reactor
from twisted.web.resource import Resource

    class Server(protocol.Protocol):
        def dataReceived(self, data):
            #do something on the server side

        def message(self)
            #send message to clients

    class HelloResource(Resource):
        isLeaf = True

        def render_GET(self,request):
            return "<html>Hello, world!</html>"

factory = protocol.Factory()
factory.protocol = Server
reactor.listenTCP(1234, factory)

reactor.listenTCP(8080, server.Site(HelloResource()))

reactor.run()
Was it helpful?

Solution 2

If you want to do things this way, your Server.message obviously has to be a @classmethod, and it has to have access to a list of clients, and send the message to each of them.

Something like this:

class Server(protocol.Protocol):
    clients = set()

    def dataReceived(self, data):
        #do something on the server side
        pass

    def connectionMade(self):
        Server.clients.add(self)

    def connectionLost(self):
        Server.clients.remove(self)

    @classmethod
    def message(cls):
        for client in cls.clients:
            client.transport.write('got GET request\n')

Now you can just call Server.message() from your render_GET method.

I'm not sure this is the best design—really, there are all kinds of better objects to hang a list of clients on than the protocol class—but it should work.

OTHER TIPS

This is very similar to a question answered in the Twisted FAQ.

Essentially, you need to make the protocol instances created by your factory accessible to the resources that make up your web server.

A simple way to do this is to have your factory keep a list of protocol instances (read about buildProtocol if you haven't yet) and then pass the factory instance to your HelloResource initializer, then have that initializer save the factory as an attribute on the HelloResource instance.

This would HelloResource access to a list of protocol instances - by way of the factory object it now has a reference to - which it could then iterate over and, for example, call methods on each protocol instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top