[Twisted-Python] Keeping a list of connected PB clients

Yi Qiang yqiang at gmail.com
Sat Nov 25 12:33:01 MST 2006


On 11/24/06, Phil Christensen <phil at bubblehouse.org> wrote:

> The place where you want to do all this is really in your Realm
> instance. I think it's possible to create a PB server that doesn't
> require login, but I've never had any need for it, so you're kind of
> on your own there.


Hi Phil,
Thanks for the reply.  My implementation is very similar to what you
described below.  I am having the clients pass in a 'mind' object that's
representative of them, which is good enough to keep track of some
information.  What I am having trouble with is getting access to the clients
IP address.  This is not something I can pass in in the PBClientFactory's
login method, since many computers are NAT'ed.

> class MyRealm:
> >     """
> >     Holds a reference to the main service object.
> >     """
> >     __implements__ = portal.IRealm
> >
> >     def __init__(self, service):
> >         """
> >         Create a realm with the given service.
> >         """
> >         self.service = service
> >
> >     def requestAvatar(self, avatarId, mind, *interfaces):
> >         """
> >         This function is called after the user has verified their
> >         identity. It returns an object that represents the user
> >         in the system, i.e., an avatar.
> >         """
> >         if pb.IPerspective in interfaces:
> >             avatar = self._getPBAvatar(avatarId, mind)
> >             ####################### <-- RIGHT HERE
> >             return pb.IPerspective, avatar, avatar.logout
> >         else:
> >             raise NotImplementedError("no interface")
>
> This is where you want to maintain your client list. The hardest part
> is deciding on a place to put it that will be accessible from all
> your code; I usually use a singleton pattern of some kind, where I
> can import a module that holds onto client references and provides
> functions to manipulate/retrieve that list.


Yes, this is something I do have trouble with.  I will look into the
singleton pattern.  It would be nicer if there was a convenient way to
bubble up the  list of clients.

So, that point where I put all those hashes is a pretty good place to
> add clients your client queue. The 'mind' argument is usually a
> reference to the client on the other end, assuming your client passes
> it properly. My client does this:
>
> >     # self.client is a Referenceable on the client side.
> >     defer = self.factory.login(credentials.UsernamePassword
> > (username, password), self.client)
> >     defer.addCallback(connected_callback, self)


I do the same thing.

>
>
> There's a lot of flexibility there. You could move the
> clienttracker.append call right inside your Avatar constructor -- the
> only reason I didn't is because my server supports a number of
> protocols besides PB, and I wanted to deal with them universally.
>
> One thing this approach doesn't do is keep track of clients that
> connect, but fail authentication. To do that, you'd need to subclass
> Broker, but that's a tough one. I looked into this once before, and
> it certainly appears doable -- in the end, a Broker is still a
> Protocol, which means it has a transport property you can get client
> addresses out of.


This is exactly what I need to do so I can associate a client with both
their username and ip address.  I have access to the broker if I subclass
PBServerFactory, but I am not sure how to access it from the Realm, or if it
is possible at all.

Any suggestions would be appreciated!

Thanks,
Yi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20061125/d59f9b6a/attachment.html>


More information about the Twisted-Python mailing list