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