zoukankan      html  css  js  c++  java
  • Python的XMLRPC机制:实现跨进程间、client/server端通信

    SimpleXMLRPCServer模块式python语言的一个基于 xml 格式的进程间通信的基础框架。

    SimpleXMLRPCServer是一个单线程的服务器,这意味着,如果几个客户端同时发出多个请求,其它的请求就必须等待第一个请求完成以后才 能继续。此处也有一个解决方法。

    例子代码如下:

    创建一个server端主进程,并且利用一个线程开启一个server线程,并开启一个client进程作为child 进程。

    MyRemoteService包含三个serveice服务方法,我们测试Add方法,从server端返回计算结果。
    #-*- coding: UTF-8 -*-
    
    import wx
    import threading
    import sys
    from SimpleXMLRPCServer import SimpleXMLRPCServer
    
    
    class XMLRPCServerThread(threading.Thread):
        def __init__(self, remoteServiceInstance, host='127.0.0.1', port=1234):
            self._RemoteServiceInstance = remoteServiceInstance
            self._Host = host
            self._Port = port
            threading.Thread.__init__(self)
    
        def stop(self):
            self._Server.shutdown()    
    
        def run(self):
            self._Server = SimpleXMLRPCServer( (self._Host, self._Port), logRequests=False, allow_none = True )
            self._Server.register_instance( self._RemoteServiceInstance )
            self._Server.serve_forever()
    
    class MyRemoteService(object):
    
        def __init__(self, obj):
            self.obj = obj
    
        def Add(self, a, b):
            return a + b
        
        def NoReturn(self):
            print 'xxxx'
        
        def Empty(self):
            return u'中国 .'
            
    class MyFrame(wx.Frame):
    
        def __init__(self, parent):
    
            wx.Frame.__init__(self, parent, -1, "Server service")
    
            mainPanel = wx.Panel(self,  size = (300, 400))
            mainPanel.SetBackgroundColour(wx.Colour(0,122,200))
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(mainPanel, 1, wx.EXPAND)
            self.SetSizerAndFit(sizer)
                    
    
    ## @detail ShellApp主应用程序的核
    class ShellApp(wx.App):
        
        def OnInit(self):
            mainFrame = MyFrame(None)
            
            self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
            self.__ServerThread = self.__GetRPCThread()
            self.__ChildProcess = wx.Process(self)
            pid = wx.Execute('python remoteClient.py', wx.EXEC_NOHIDE|wx.EXEC_ASYNC, self.__ChildProcess)        
            mainFrame.Show(True)           
            
            return True
        
        
        def __GetRPCThread(self, host='localhost', port=1234):
            remoteObj = MyRemoteService(self)
            rpcThread = XMLRPCServerThread(remoteObj, host, port)
            rpcThread.start()
            return rpcThread
        
        def OnProcessEnded(self, evt):
            print 'Child process exist'
            self.__ChildProcess.Destroy()
            self.__ServerThread.stop()
            self.Exit()
               
    # @detail main程序的主入口程序   
    if __name__ == '__main__':  
        app = ShellApp()
        
        #重新定向wxpython的输出输入和错误输出到系统标准输入输出
        sys.stdin = sys.__stdin__
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        app.MainLoop()

    client端代码如下:

    #-*- coding: UTF-8 -*-
    import wx
    import sys
    import xmlrpclib  #客户端
    
    from SimpleXMLRPCServer import SimpleXMLRPCServer
    
    class MyFrame(wx.Frame):
    
        def __init__(self, parent):
            wx.Frame.__init__(self, parent, -1, "Client app")
            mainPanel = wx.Panel(self,  size = (300, 200))
            
            addButton = wx.Button(mainPanel, -1, 'Add')
            addButton.Bind(wx.EVT_BUTTON, self.__OnAddClicked)
            self._AText = wx.TextCtrl(mainPanel, -1, '10')
            self._AddText = wx.StaticText(mainPanel, -1, ' + ')
            self._BText = wx.TextCtrl(mainPanel, -1, '23')
            self._Label = wx.StaticText(self, -1, ' = ')
            self._SumText = wx.TextCtrl(mainPanel)
            panelSizer = wx.BoxSizer(wx.HORIZONTAL)
            panelSizer.Add(addButton, 0, wx.ALL, 6)        
            panelSizer.Add(self._AText, 0, wx.ALL, 6)
            panelSizer.Add(self._AddText, 0, wx.ALL, 6)
            panelSizer.Add(self._BText, 0, wx.ALL, 6)
            panelSizer.Add(self._Label, 0, wx.ALL, 6)
            panelSizer.Add(self._SumText, 0, wx.ALL, 6)
            mainPanel.SetSizer(panelSizer)
            
            mainPanel.SetBackgroundColour(wx.Colour(122,12,20))
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(mainPanel, 1, wx.EXPAND)
            self.SetSizerAndFit(sizer)
            self._Proxy = xmlrpclib.ServerProxy('http://127.0.0.1:1234') 
        
        def __OnAddClicked(self, evt):
            a = int(self._AText.GetLabel())
            b = int(self._BText.GetLabel())
            sum = self._Proxy.Add(a, b)
            self._SumText.SetLabel('%s'%sum)
            self._Proxy.NoReturn()
    
    ## @detail ShellApp主应用程序的核
    class ShellApp(wx.App):    
        def OnInit(self):
            mainFrame = MyFrame(None)
            mainFrame.Show(True)          
            return True
        
               
    # @detail main程序的主入口程序   
    if __name__ == '__main__':  
        app = ShellApp()
        
        #重新定向wxpython的输出输入和错误输出到系统标准输入输出
        sys.stdin = sys.__stdin__
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        app.MainLoop()

    运行结果如下:

  • 相关阅读:
    点灯
    流水灯
    <<晨间日记>>要点
    PL/SQL 函数学习 Start with...Connect By
    FTP Put步骤回顾
    ORA16038,ORA19809,ORA00312无法归档的解决方法
    Emacs for windows
    ORA01578,ORA01115,ORA01110 ORACLE 数据块损坏
    MySQL存储过程的调优过程
    ORA01110 数据文件日志文件丢失打不开数据库
  • 原文地址:https://www.cnblogs.com/ankier/p/3231288.html
Copyright © 2011-2022 走看看