Using SimpleXMLRPCServer in a Windows Service

Rudy Schockaert rudy.schockaert at gmail.com
Thu Nov 23 04:52:53 EST 2006


After some Googling I found a post of someone who wanted to do exactly
as what I want to do now.
There is however a problem in his code that makes the service fails
after the first connection. I slightly modified his code and now I can
run the service longer before I run into trouble.
I then tried making the SimpleXMLRPCServer multi-threaded, hoping the
problem would disappear, but no avail.
The code is as follows:
The commented part in the while loop is from the original code.
<CODE>


## XML-RPC Service
import sys
import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import win32file
import servicemanager
import SimpleXMLRPCServer
import SocketServer
import select

class OBJECT:
    def hello(self, text):
        return "Hello World (%s)" % text

class ThreadedSimpleXMLRPCServer(SocketServer.ThreadingMixIn,
SimpleXMLRPCServer.SimpleXMLRPCServer): pass

class XMLRPCSERVICE(win32serviceutil.ServiceFramework):
    _svc_name_ = "XMLRPCSERVICE"
    _svc_display_name_ = "XMLRPCSERVICE"
    _svc_description_ = "XMLRPCSERVICE"

    def __init__(self, args):
        win32evtlogutil.AddSourceToRegistry(self._svc_display_name_,
sys.executable, "Application")
        win32serviceutil.ServiceFramework.__init__(self, args)

        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.hSockEvent = win32event.CreateEvent(None, 0, 0, None)
        self.stop_requested = 0

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.stop_requested = 1
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        ## Write a started event
        servicemanager.LogMsg(
            servicemanager.EVENTLOG_INFORMATION_TYPE,
            servicemanager.PYS_SERVICE_STARTED,
            (self._svc_name_, ' (%s)' % self._svc_name_))

        server = ThreadedSimpleXMLRPCServer(("", 8080))
        object = OBJECT()
        server.register_instance(object)
        self.socket = server.socket

        while 1:
            r, w, x = select.select([self.socket],[],[],10)
            if r == [self.socket]:
                server.handle_request()
            if self.stop_requested:
                self.socket.close()
                break


            #win32file.WSAEventSelect(server,
self.hSockEvent,win32file.FD_ACCEPT)
            #rc =
win32event.WaitForMultipleObjects((self.hWaitStop,self.hSockEvent), 0,
win32event.INFINITE)
            #if rc == win32event.WAIT_OBJECT_0:
            #    break
            #else:
            #    server.handle_request()
            #    win32file.WSAEventSelect(server,self.hSockEvent, 0)
            #    #server.serve_forever()  ## Works, but breaks the

        ## Write a stopped event
        win32evtlogutil.ReportEvent(self._svc_name_,
                                    servicemanager.PYS_SERVICE_STOPPED,0,
                                    servicemanager.EVENTLOG_INFORMATION_TYPE,
                                    (self._svc_name_,""))

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(XMLRPCSERVICE)


</CODE>

I tested with the following:

<CODE>

import xmlrpclib
import time

server = xmlrpclib.ServerProxy("http://localhost:8080")
for i in range(100):
    print server.hello("%d" % i)
    time.sleep(1)

</CODE>

The loop ends with the following error:

<OUTPUT>
Hello World (0)
...
Hello World (44)
Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py",
line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\DATA\TestSoap.py", line 6, in ?
    print server.hello("%d" % i)
  File "C:\Python24\lib\xmlrpclib.py", line 1096, in __call__
    return self.__send(self.__name, args)
  File "C:\Python24\lib\xmlrpclib.py", line 1383, in __request
    verbose=self.__verbose
  File "C:\Python24\lib\xmlrpclib.py", line 1137, in request
    headers
ProtocolError: <ProtocolError for localhost:8080/RPC2: -1 >
</OUTPUT>

Can someone help me in creating a windows service that allows me to
handle XMLRPC request?

Thanks in advance,

Rudy Schockaert



More information about the Python-list mailing list