[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