Simple example of setting up a distributed message oriented request/reply architecture. Shows creation of a central exchange service which all participating processes connect to. Services assign themselves a name and export the methods which are remotely accessible. Client services are then able to make calls against the exported methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | # The exchange process which everything connects to.
import netsvc
import signal
dispatcher = netsvc.Dispatcher()
dispatcher.monitor(signal.SIGINT)
exchange = netsvc.Exchange(netsvc.EXCHANGE_SERVER)
exchange.listen(11111)
dispatcher.run()
# The server side of the interaction.
import netsvc
import signal
class Service(netsvc.Service):
def __init__(self):
netsvc.Service.__init__(self,"math")
self.joinGroup("web-services")
self.exportMethod(self.multiply)
def multiply(self,x,y):
return x*y
dispatcher = netsvc.Dispatcher()
dispatcher.monitor(signal.SIGINT)
exchange = netsvc.Exchange(netsvc.EXCHANGE_CLIENT)
exchange.connect("localhost",11111,5)
service = Service()
dispatcher.run()
# The client side of the interaction.
import netsvc
import signal
import random
class Client(netsvc.Service):
def __init__(self):
netsvc.Service.__init__(self,"")
self.startTimer(self.call,1,"1")
def call(self,name):
service = self.serviceEndPoint("math")
if service != None:
x = int(random.random()*1000)
id = service.multiply(x,x)
self.monitorResponse(self.result,id)
self.startTimer(self.call,1,"1")
def result(self,square):
print square
dispatcher = netsvc.Dispatcher()
dispatcher.monitor(signal.SIGINT)
exchange = netsvc.Exchange(netsvc.EXCHANGE_CLIENT)
exchange.connect("localhost",11111,5)
client = Client()
dispatcher.run()
# A gateway which allows XML-RPC style requests to the same service.
import signal
import netsvc
import netsvc.xmlrpc
dispatcher = netsvc.Dispatcher()
dispatcher.monitor(signal.SIGINT)
httpd = netsvc.HttpDaemon(8000)
rpcgw = netsvc.xmlrpc.RpcGateway("web-services")
httpd.attach("/xmlrpc/service",rpcgw)
httpd.start()
exchange = netsvc.Exchange(netsvc.EXCHANGE_CLIENT)
exchange.connect("localhost",11111,5)
dispatcher.run()
|
This provides an alternative to systems dependent on XML-RPC and SOAP which only create connections to other processes when required. In this architecture the processes are always connected through the central exchange process, avoiding the cost of setting up and ripping down the socket connections for each request. That said, an XML-RPC or SOAP gateway can also be connected into the system to allow such remote access using the HTTP protocol. Although each service is shown in a separate process, they could just as well be in the same process as the means of communication is the same. The services shown may also publish data with other services subscribing to that data if required.
The "netsvc" module is provided as part of OSE which is available from: