اذا لم تكن مهتما ب XML-RPC فكن حرا للإنتقال للفصل القادم
فى ابسط الصور XML-RPC هو بروتوكول Remote Procedure Call عبر بروتوكول HTTP
للمزيد
http://en.wikipedia.org/wiki/XML-RPCنوضح الموضوع بمثال بسيط
#!bin/python
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
from SocketServer import ThreadingMixIn
class Greeter(object):
def hi(self):
"""Returns hi message"""
return "Hi"
def bye(self):
"""Returns bye message"""
return "Bye"
def say(self, what):
"""Returns Simone says message"""
return "Simone says: "+ what
class MyServer(ThreadingMixIn, SimpleXMLRPCServer):
pass
def test():
addr=('', 40002)
srvr=MyServer(addr, SimpleXMLRPCRequestHandler)
srvr.register_instance(Greeter())
srvr.register_introspection_functions()
srvr.serve_forever()
#print "Started..."
if __name__=="__main__":
test()
للوهلة الأولى سيتبادر لذهنك اننا ننشئ سرفر متعدد الخيوط (ThreadingMixIn واستخدمنا بدل ال SocketServer صف مشابة وهو SimpleXMLRPCServer ؟
نعم بالفعل
ولدينا صف عادى جدا
class Greeter(object):
def hi(self):
"""Returns hi message"""
return "Hi"
def bye(self):
"""Returns bye message"""
return "Bye"
def say(self, what):
"""Returns Simone says message"""
return "Simone says: "+ what
كل ماهنالك اننا نريد ان نتيح امكانية استخدام طرق ذلك الصف عبر ال HTTP
لكائن SimpleXMLRPCServer بعض الطرق مثل register_instance اللتى تقوم بتسجيل ذلك الكائن على السرفر
وregister_introspection_functions تقوم بتسجيل بعض الدوال لمعرفة مايتعلق بذلك الكائن مثل system.listMethods (للحصول على الطرق الخاصة به ) و system.methodSignature للحصول على توقيع الطريقة (اسمها والمعاملات وال retrun ) و methodHelp للحصول على نص المساعدة الخاص بالطريقة وذلك بوضع اسمها كمعامل لهذه الطريقة
srvr.register_instance(Greeter())
srvr.register_introspection_functions()
قم بتشغيل ال سرفر ونأتى للعميل
import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:40002')
print s.system.listMethods()
print s.hi()
print s.bye()
print s.say("Something")
print s.system.methodHelp('say')
1- ننشئ كائن ServerProxy نحدد فيه عنوان السرفر ورقم البورت اللذى ينصت اليه
s = xmlrpclib.ServerProxy('http://localhost:40002')
2- للحصول على قائمة الطرق المتاحة على السرفر نستخدم system.listMethods
3- استغلال الطرق المتاحة مثل استدعاء الطرق hi اوbye
print s.hi()
print s.bye()
4- ايضا استغلال الطرق اللتى قد تأخذ معاملات ما مثل say
سيكون الناتج
striky@striky-desktop:~/workspace/pytut/src$ python xmlrpcclient1.py
['bye', 'hi', 'say', 'system.listMethods', 'system.methodHelp', 'system.methodSignature']
Hi
Bye
Simone says: Something
Returns Simone says message
يوجد صف اخر وهو المفضل استخدامه DocXMLRPCServer وذلك للمساعدة فى عرض ال documentation ايضا

DocXMLRPCServer
مثل سابقه ولكن له بعض الطرق الإضافية مثل set_server_title لوضع العنوان و set_server_name لوضع اسمه فى اعلى الصفحة و set_server_documenation لوضع وثيقة خاصة به
from DocXMLRPCServer import DocXMLRPCServer, DocXMLRPCRequestHandler
from SocketServer import ThreadingMixIn
class Greeter(object):
def hi(self):
"""Returns hi message"""
return "Hi"
def bye(self):
"""Returns bye message"""
return "Bye"
def say(self, what):
"""Returns Simone says message"""
return "Simone says: "+ what
class MyServer(ThreadingMixIn, DocXMLRPCServer):
pass
def test():
addr=('', 40002)
srvr=MyServer(addr, DocXMLRPCRequestHandler)
##server methods...
srvr.set_server_title("My First DocXMLRPC Server")
srvr.set_server_name("Greeter DocXMLRPC Server")
srvr.set_server_documentation("Greeter DocXMLRPC Server is used for learning XML-RPC")
srvr.register_instance(Greeter())
srvr.register_introspection_functions()
srvr.serve_forever()
#print "Started..."
if __name__=="__main__":
test()
تستطيع الإستفادة من هذا السرفر فى لغات اخرى مثل روبى مثلا
##Ruby
striky@striky-desktop:~$ irb
irb(main):001:0> require "xmlrpc/client"
=> true
irb(main):002:0> require "pp"
=> true
irb(main):004:0> s=XMLRPC::Client.new2("http://localhost:40002")
=> #<XMLRPC::Client:0xb7aa2a50 @user=nil, @proxy_port=nil, @auth=nil, @cookie=nil, @create=nil, @port=40002, @http=#<Net::HTTP localhost:40002 open=false>, @proxy_host=nil, @http_last_response=nil, @parser=nil, @timeout=30, @path="/RPC2", @password=nil, @http_header_extra=nil, @use_ssl=false, @host="localhost">
irb(main):005:0> s
=> #<XMLRPC::Client:0xb7aa2a50 @user=nil, @proxy_port=nil, @auth=nil, @cookie=nil, @create=nil, @port=40002, @http=#<Net::HTTP localhost:40002 open=false>, @proxy_host=nil, @http_last_response=nil, @parser=nil, @timeout=30, @path="/RPC2", @password=nil, @http_header_extra=nil, @use_ssl=false, @host="localhost">
irb(main):006:0> s.call('hi')
=> "Hi"
irb(main):007:0> s.call('bye')
=> "Bye"
irb(main):008:0> s.call('say', "Hello, World!")
=> "Simone says: Hello, World!"