PythonGuide/XML-RPC
من PFWiki
محتويات |
XML-RPC
اذا لم تكن مهتما ب 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
print s.say("Something")
سيكون الناتج
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
يوجد صف اخر وهو المفضل استخدامه DocXMLRPCServer وذلك للمساعدة فى عرض ال documentation ايضا
مثل سابقه ولكن له بعض الطرق الإضافية مثل 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!"
