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 19 years, 9 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 18 years, 10 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 16 years, 6 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 14 years, 8 months 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 13 years, 3 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()