Welcome, guest | Sign In | My Account | Store | Cart

this shows how to enable a SimpleXMLRPCServer to be cleanly killed (exited) by a client.

Python, 19 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from SimpleXMLRPCServer import *

class MyServer(SimpleXMLRPCServer):

    def serve_forever(self):
	self.quit = 0
	while not self.quit:
	    self.handle_request()


def kill():
    server.quit = 1
    return 1
    

server = MyServer(('127.0.0.1', 8000))
server.register_function(kill)

server.serve_forever()

I couldn't find a simple solution to the problem of ending a Server remotely. So, I hope this gives a simple example of one way to do it.

5 comments

Brian Quinlan 22 years, 2 months ago  # | flag

Easier way. You could also express this as:

quit = 0
def kill():
   
global quit
    quit
= 1

server
= MyServer(('127.0.0.1', 8000))
server
.register_function(kill)

while not quit:
    server
.handle_request()

This saves you the hassle of subclassing SimpleXMLRPCServer.

Jeff Bauer 21 years, 3 months ago  # | flag

return value. Brian Quinlan adds a nice enhancement to the original code. But don't forget to add a return statement to the kill function.

def kill():
   
global quit
    quit
= 1
   
return 1
Bob Gailer 18 years, 11 months ago  # | flag

Slicker?

import SimpleXMLRPCServer
class Server:
    quit
= False
   
def __init__(self):
       
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8888))
       
self.server.register_instance(self)
       
while not self.quit:
           
self.server.handle_request()
   
def shutdown(self):
       
self.quit = True
       
return 0
   
def other_functions():pass
Server()
Andrew E 17 years ago  # | flag

Handling signals better. The idea is good but doesn't seem to help me with handling signals like Ctrl+C in the console too well.

Below I have put a complete, standalone script that provides an alternative server that has built-in support to map signals to a clean shutdown and an exposable shutdown method if you want to allow that via XML-RPC.

There are pros/cons to using a subclass approach, but it may be useful for some...

#!/usr/bin/env python
import socket, signal
from SimpleXMLRPCServer import *

class AltXMLRPCServer(SimpleXMLRPCServer):

    finished
=False

   
def register_signal(self, signum):
        signal
.signal(signum, self.signal_handler)

   
def signal_handler(self, signum, frame):
       
print "Caught signal", signum
       
self.shutdown()

   
def shutdown(self):
       
self.finished=True
       
return 1

   
def serve_forever(self):
       
while not self.finished: server.handle_request()


class MyFuncs:
   
def div(self, x, y) :
       
"""Returns division of two numbers"""
       
return x // y

   
def add(self, x, y) : return x + y


hostname
=socket.gethostname(); port=8086
server
= AltXMLRPCServer((hostname, port))
print "Serving on %s:%d" %(hostname, port)
server
.register_function(pow)
server
.register_function(server.shutdown)
server
.register_function(lambda x,y: x-y, 'minus')
server
.register_introspection_functions()
server
.register_instance(MyFuncs())
server
.register_signal(signal.SIGHUP)
server
.register_signal(signal.SIGINT)

server
.serve_forever()
print "Closed"
tolomea 15 years, 7 months ago  # | flag

Thank you for that, it works a charm, although there is a small typo, this line: while not self.finished: server.handle_request() should probably read while not self.finished: self.handle_request()