[Twisted-Python] How to create a new service and listen on a new port?

Hi all, This is my first post here, and I'm not a native English speaker, so please bear with me :) I'm trying to implement something like this: * A UDP server listening on port1 for incoming request * A client sends the requset to port1 * The server confirms the request and creates another (different) UDP service on a new port (port2) * The client then would be able to connect to port2 and do some other things... By reading this "Writing a New Plug-In for mktap" - http://twistedmatrix.com/projects/core/documentation/howto/plugin.html I've implemented a UDP server and could run it with "twisted -f". Now the server receives request on port1, and creates a new service at port2 for client to connect to it. I implemented this as the following: class FooServer(DatagramProtocol): def datagramReceived(self, data, addr): # do something to verify the request and send the client with a confirm msg reactor.listenUDP(port2, AnotherService()) reactor.run() class AnotherService(DatagramProtocol): # ... I got this up and run under windows cmd console, however, whenever I try to stop the server with Ctrl + c or close the cmd console, the server died in a dead loop which keeps produces tone of error messages. The only way to quit that console is to "kill" it... I know there must be something wrong. I would like to know: * How could I accomplish this in a more elegant/"formal" way? I'm very new to twisted and this mailing list, if someone has asked similar question before, please tell me how to find it. (BTW, how could I search the mailinglist?) Thanks in advance! :D

Killing the process is quite normal in early stage development. Twisted even helps with this by writing a pid file if you demonize it. There are a number of more elegant techniques. If you intend to always run it from the command line as a non demon then write a control-c handler that gracefully stops your process. def ctrlCHandler(*whatever): print "Interupted" for thread in threads: thread.stop() thread.join() signal.signal(signal.SIGINT, ctrlCHandler) (this is from a non-twisted application with threads :-) - I don't know if the signal thingy works on windows either) The other option is to build a stop mechanism - I'm not sure from your description what your app does but you could send it a 'STOP' datagram for example that would cause it to stop nicely. Or when you have your client connection set up allow the client to terminate the process in a similar way. you should be able to search the list at http://gmane.org/ although I find gmane has a very poor UI and I find its search a bit mysterious too. cheers mark On 23 May 2005, at 06:49, Eric Hsu wrote:

Hi mark, big thanks for your quick reply :) I guess I haven't make myself clear enough (sorry for my poor English... ) I'm not looking for a way to shutdown/stop my server :p My question is, should I implement my requirments in the following way? (Use the "raw" reactor to create a new service and listen on a new port?) [code] class FooServer(DatagramProtocol): def datagramReceived(self, data, addr): # do something to verify the request and send the client with a confirm msg reactor.listenUDP(port2, AnotherService()) reactor.run() class AnotherService(DatagramProtocol): # ... [/code] I've already write my server as a "plugin" to the twisted framework (as the tutorial tought me), now I want to create a new service within my server, is there a more elegant/"formal" way?

On Mon, 23 May 2005 13:49:21 +0800, Eric Hsu <nkeric@gmail.com> wrote:
Since nothing is likely to call datagramReceived unless the reactor is running, and calling reactor.run() while the reactor is running is a terribly broken thing to do, the above code is likely mistaken in calling reactor.run(). I bet shutdown behavioor will become much nicer if you remove the call to reactor.run() here, and in any other similar places. twistd will start and stop the reactor for you. Jp

2005/5/23, Jp Calderone <exarkun@divmod.com>:
Mmm... you're right! However, it seems that without reactor.run(), the newly created AnotherService instance would not serve the client as expected... but it will with reactor.run().. that's why I'm looking for a better/elegant/formal way to achieve what I want, any ideas? best regards - Eric

Now I've figured out the solution! Just remove the "reactor.run()" as Jp suggestion! Here is the sample code which fulfills my requirements: class AClass(DatagramProtocol): def datagramReceived(self, data, addr): # do something... anotherService1 = reactor.listenUDP(port1, AnotherService()) anotherService2 = reactor.listenUDP(port2, AnotherService()) # ... anotherServiceN = reactor.listenUDP(portN, AnotherService()) # if we want to stop one of the AnotherServiceS, just anotherServiceX.stopListening() class AnotherService(DatagramProtocol): def datagramReceived(self, data, addr): # blah blah blah... Thank you all guys! 2005/5/23, Eric Hsu <nkeric@gmail.com>:

Killing the process is quite normal in early stage development. Twisted even helps with this by writing a pid file if you demonize it. There are a number of more elegant techniques. If you intend to always run it from the command line as a non demon then write a control-c handler that gracefully stops your process. def ctrlCHandler(*whatever): print "Interupted" for thread in threads: thread.stop() thread.join() signal.signal(signal.SIGINT, ctrlCHandler) (this is from a non-twisted application with threads :-) - I don't know if the signal thingy works on windows either) The other option is to build a stop mechanism - I'm not sure from your description what your app does but you could send it a 'STOP' datagram for example that would cause it to stop nicely. Or when you have your client connection set up allow the client to terminate the process in a similar way. you should be able to search the list at http://gmane.org/ although I find gmane has a very poor UI and I find its search a bit mysterious too. cheers mark On 23 May 2005, at 06:49, Eric Hsu wrote:

Hi mark, big thanks for your quick reply :) I guess I haven't make myself clear enough (sorry for my poor English... ) I'm not looking for a way to shutdown/stop my server :p My question is, should I implement my requirments in the following way? (Use the "raw" reactor to create a new service and listen on a new port?) [code] class FooServer(DatagramProtocol): def datagramReceived(self, data, addr): # do something to verify the request and send the client with a confirm msg reactor.listenUDP(port2, AnotherService()) reactor.run() class AnotherService(DatagramProtocol): # ... [/code] I've already write my server as a "plugin" to the twisted framework (as the tutorial tought me), now I want to create a new service within my server, is there a more elegant/"formal" way?

On Mon, 23 May 2005 13:49:21 +0800, Eric Hsu <nkeric@gmail.com> wrote:
Since nothing is likely to call datagramReceived unless the reactor is running, and calling reactor.run() while the reactor is running is a terribly broken thing to do, the above code is likely mistaken in calling reactor.run(). I bet shutdown behavioor will become much nicer if you remove the call to reactor.run() here, and in any other similar places. twistd will start and stop the reactor for you. Jp

2005/5/23, Jp Calderone <exarkun@divmod.com>:
Mmm... you're right! However, it seems that without reactor.run(), the newly created AnotherService instance would not serve the client as expected... but it will with reactor.run().. that's why I'm looking for a better/elegant/formal way to achieve what I want, any ideas? best regards - Eric

Now I've figured out the solution! Just remove the "reactor.run()" as Jp suggestion! Here is the sample code which fulfills my requirements: class AClass(DatagramProtocol): def datagramReceived(self, data, addr): # do something... anotherService1 = reactor.listenUDP(port1, AnotherService()) anotherService2 = reactor.listenUDP(port2, AnotherService()) # ... anotherServiceN = reactor.listenUDP(portN, AnotherService()) # if we want to stop one of the AnotherServiceS, just anotherServiceX.stopListening() class AnotherService(DatagramProtocol): def datagramReceived(self, data, addr): # blah blah blah... Thank you all guys! 2005/5/23, Eric Hsu <nkeric@gmail.com>:
participants (3)
-
Eric Hsu
-
Jp Calderone
-
mark