[Twisted-Python] Is AMP a bidirectional protocol?
Is the AMP protocol bidirectional (beyond the response you get to each message)? I'm really new to Twisted, and I followed the ampserver.py and ampclient.py examples to get an AMP connection working, because someone suggested that to me as an easy protocol to start with. Although sending a message from the client to the server works fine, I can't figure out how to initiate a message from the server to the client over the connection that the client initially created. I'm working on a little project where the "server" and the "client" actually need to talk more like peers where each can initiate a message to the other. The server is outside the NAT, so it'd be best if the communication could happen both ways over the connection that the client initiates. Could someone point me in the right direction? I can provide my existing code if that makes any difference. ~ Nathan
On Wed, Feb 27, 2008 at 12:57 PM, Nathan <nathan.stocks@gmail.com> wrote:
Is the AMP protocol bidirectional (beyond the response you get to each message)?
Yes: http://djfroofy.livejournal.com/3509.html -- \\\\\/\"/\\\\\\\\\\\ \\\\/ // //\/\\\\\\\ \\\/ \\// /\ \/\\\\ \\/ /\/ / /\/ /\ \\\ \/ / /\/ /\ /\\\ \\ / /\\\ /\\\ \\\\\/\ \/\\\\\/\\\\\/\\\\\\ d.p.s
On Wed, Feb 27, 2008 at 11:50 AM, Drew Smathers <drew.smathers@gmail.com> wrote:
On Wed, Feb 27, 2008 at 12:57 PM, Nathan <nathan.stocks@gmail.com> wrote:
Is the AMP protocol bidirectional (beyond the response you get to each message)?
Drew, you're everywhere! Ok, so next question: How do you access the callRemote method from outside the protocol itself on the server side? In the example above, from the server's main() could you call pf.protocol.CallRemote()? ~ Nathan
On Wed, Feb 27, 2008 at 2:09 PM, Nathan <nathan.stocks@gmail.com> wrote:
On Wed, Feb 27, 2008 at 11:50 AM, Drew Smathers <drew.smathers@gmail.com> wrote:
On Wed, Feb 27, 2008 at 12:57 PM, Nathan <nathan.stocks@gmail.com> wrote:
Is the AMP protocol bidirectional (beyond the response you get to each message)?
Drew, you're everywhere!
Ok, so next question:
How do you access the callRemote method from outside the protocol itself on the server side? In the example above, from the server's main() could you call pf.protocol.CallRemote()?
I think looking at David's chat demo will steer you in the right direction: http://ripton.net/hg/ampchat/file/90a4007ef2a7/chatserver.py In a nutshell - just keep them in list or dict bound to the factory and be sure to do cleanup on connectionLost. -- \\\\\/\"/\\\\\\\\\\\ \\\\/ // //\/\\\\\\\ \\\/ \\// /\ \/\\\\ \\/ /\/ / /\/ /\ \\\ \/ / /\/ /\ /\\\ \\ / /\\\ /\\\ \\\\\/\ \/\\\\\/\\\\\/\\\\\\ d.p.s
On Wed, Feb 27, 2008 at 1:47 PM, Drew Smathers <drew.smathers@gmail.com> wrote:
On Wed, Feb 27, 2008 at 2:09 PM, Nathan <nathan.stocks@gmail.com> wrote:
On Wed, Feb 27, 2008 at 11:50 AM, Drew Smathers <drew.smathers@gmail.com> wrote:
On Wed, Feb 27, 2008 at 12:57 PM, Nathan <nathan.stocks@gmail.com> wrote:
Is the AMP protocol bidirectional (beyond the response you get to each message)?
Drew, you're everywhere!
Ok, so next question:
How do you access the callRemote method from outside the protocol itself on the server side? In the example above, from the server's main() could you call pf.protocol.CallRemote()?
I think looking at David's chat demo will steer you in the right direction:
http://ripton.net/hg/ampchat/file/90a4007ef2a7/chatserver.py
In a nutshell - just keep them in list or dict bound to the factory and be sure to do cleanup on connectionLost.
Ok, so after much staring at code, it looks the pattern is as follows: 1) Create a custom factory class that subclasses ServerFactory and adds a dict to store "protocol" objects and sets its own self.protocol to the custom protocol that subclasses amp.AMP. 2) Somewhere in the custom protocol (He did it in a login function, but I'm assuming I could do it in connectionMade if I wanted to?), access the factory's dict through self.factory.whatever and stick "self" (the current protocol object) in the dict, preferably keyed by some identifier that lets you pick out the one you want later (ServerFactory.protocol <=> AMP.factory ... so circular!) 3) Send messages from the server to a specific client with your_factory.somedict[identifier].callRemote(SomeCommand) Did I get that right? ~ Nathan
On 2008.02.27 10:57:03 -0700, Nathan wrote:
Is the AMP protocol bidirectional (beyond the response you get to each message)?
Yes.
I'm really new to Twisted, and I followed the ampserver.py and ampclient.py examples to get an AMP connection working, because someone suggested that to me as an easy protocol to start with. Although sending a message from the client to the server works fine, I can't figure out how to initiate a message from the server to the client over the connection that the client initially created.
I'm working on a little project where the "server" and the "client" actually need to talk more like peers where each can initiate a message to the other. The server is outside the NAT, so it'd be best if the communication could happen both ways over the connection that the client initiates.
Could someone point me in the right direction? I can provide my existing code if that makes any difference.
It was non-obvious to me too. You call callRemote on the server-side Protocol to send a message to the client side. I have a little demonstration PyGTK / AMP chat program at http://ripton.net/hg/ampchat/ -- David Ripton dripton@ripton.net
On Wed, Feb 27, 2008 at 12:10 PM, David Ripton <dripton@ripton.net> wrote:
It was non-obvious to me too.
You call callRemote on the server-side Protocol to send a message to the client side.
I have a little demonstration PyGTK / AMP chat program at http://ripton.net/hg/ampchat/
I tried to look at your demo chat program, but all I could find was a mercurial summary page. Do I need to install mercurial and check it out using that URL? (I've never used mercurial) I don't quite understand what you mean by "on the server-side Protocol." I have multiple clients connected to the server simultaneously, so if you mean (in the case of http://djfroofy.livejournal.com/3509.html ) calling TheServer.callRemote, then I don't see how it would know _which_ client to send the message to. I'm obviously misunderstanding something! ~ Nathan
On 2008.02.27 13:46:56 -0700, Nathan wrote:
On Wed, Feb 27, 2008 at 12:10 PM, David Ripton <dripton@ripton.net> wrote:
It was non-obvious to me too.
You call callRemote on the server-side Protocol to send a message to the client side.
I have a little demonstration PyGTK / AMP chat program at http://ripton.net/hg/ampchat/
I tried to look at your demo chat program, but all I could find was a mercurial summary page. Do I need to install mercurial and check it out using that URL? (I've never used mercurial)
You can do that. Or you can click around in the links within the Mercurial web interface until you see the code. (I think you want "manifest" and "file".)
I don't quite understand what you mean by "on the server-side Protocol." I have multiple clients connected to the server simultaneously, so if you mean (in the case of http://djfroofy.livejournal.com/3509.html ) calling TheServer.callRemote, then I don't see how it would know _which_ client to send the message to. I'm obviously misunderstanding something!
Each time a client connects to the server, a new protocol instance is created on the server side. When the client successfully logs in, I add the username:protocol to a dict in the server-side factory. So I know how to find clients by username. Then if someone sends a private message, I lookup the target username's protocol in the dict, and do protocol.callRemote(commands.Send, message, sender) -- David Ripton dripton@ripton.net
On Wed, Feb 27, 2008 at 12:10 PM, David Ripton <dripton@ripton.net> wrote:
On 2008.02.27 10:57:03 -0700, Nathan wrote:
Is the AMP protocol bidirectional (beyond the response you get to each message)?
Yes.
I'm really new to Twisted, and I followed the ampserver.py and ampclient.py examples to get an AMP connection working, because someone suggested that to me as an easy protocol to start with. Although sending a message from the client to the server works fine, I can't figure out how to initiate a message from the server to the client over the connection that the client initially created.
I'm working on a little project where the "server" and the "client" actually need to talk more like peers where each can initiate a message to the other. The server is outside the NAT, so it'd be best if the communication could happen both ways over the connection that the client initiates.
Could someone point me in the right direction? I can provide my existing code if that makes any difference.
It was non-obvious to me too.
You call callRemote on the server-side Protocol to send a message to the client side.
I have a little demonstration PyGTK / AMP chat program at http://ripton.net/hg/ampchat/
Oh, wow. I was looking at your example program, and thought "I should look at the amp api", so I googled "twisted amp" and the top link was: http://www.ripton.net/blog/?p=16 Which is your blog post about this thread, because of this thread. I don't know if I should be awed that Google's so dang quick, or that by my multitude of questions I'm causing the universe to change... :-) ~ Nathan
Nathan wrote:
On Wed, Feb 27, 2008 at 12:10 PM, David Ripton <dripton@ripton.net> wrote: [...]
I have a little demonstration PyGTK / AMP chat program at http://ripton.net/hg/ampchat/
Oh, wow. I was looking at your example program, and thought "I should look at the amp api", so I googled "twisted amp" and the top link was:
http://www.ripton.net/blog/?p=16
Which is your blog post about this thread, because of this thread. I don't know if I should be awed that Google's so dang quick, or that by my multitude of questions I'm causing the universe to change... :-)
Keep changing the universe. Inquiring minds want to know, and information wants to be free ;-) regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
participants (4)
-
David Ripton
-
Drew Smathers
-
Nathan
-
Steve Holden