2011-07-18 32 views
3

我有一個simpleXMLRPC服務器的問題。 我的程序中有一臺服務器可以從另一臺服務器訪問。讓我們打電話服務器其中有一個simpleXMLServer實例的計算機和客戶端另一臺服務器。simpleXMLRPC服務器python

因此,當客戶端連接到我的服務器,服務器呼叫服務器的功能。此功能有時可能需要很長時間才能執行(至5分鐘),然後發送長消息。

class Report(object):  
    __instance = None 

    def __new__(self): 
     if self.__instance is None: 
      self.__instance = object.__new__(self) 
      self.__instance.__init() 
     return self.__instance 

    def __init(self): 
     self._lastRequestTime = 0 
     self._lastRequest  = '' 
     self._minInterval  = 1 
     self._timeout   = 2 
     self.__lock   = Utils.Threading.Lock() 
     self.__lockEvent  = Utils.Threading.Lock() 
     self._event   = Utils.Threading.Event() 
     reportThread = threading.Thread(name = 'reportThread', 
             target = self.reportLoop) 
     reportThread.start() 

    def _reportAll(self): 
     tmp = Somewhere.reportAll() 
     try: 
      self.__lock.acquire() 
      self._lastRequest = tmp 
     finally: 
      self.__lock.release() 

    def reportLoop(self): 
     while 1: 
      self._event.wait() 
      self._reportAll() 
      try: 
       self.__lockEvent.acquire() 
       self._event.clear() 
      finally: 
       self.__lockEvent.release() 

    def reportAll(self): 
     if abs(Utils.Time.time() - self._lastRequestTime) > self._minInterval or len(self._lastRequest) == 0: 
      self._lastRequestTime = time.time() 
     else: 
      return self._lastRequest 

     try: 
      self.__lockEvent.acquire() 
      self._event.set()  
     finally: 
      self.__lockEvent.release() 

     try: 
      self.__lock.acquire() 
      return self._lastRequest 
     finally: 
      self.__lock.release() 

這裏是我創建服務器:

def startListen(self): 
    logging.basicConfig(level = logging.DEBUG) 
    try: 
     # Create server 
     self._server = SimpleXMLRPCServer(("192.168.0.57", 49007), requestHandler=RequestHandler) 
     self._server.register_introspection_functions() 
     self._server.register_function(Report().reportAll, 'reportAll') 
     self._server.serve_forever() 
    except: 
     return self.restart() 

爲了避免在客戶端服務器一個漫長的等待(即可以使凍結的客戶端程序),我創建了我的客戶的服務器的信號5秒後停止客戶端的線程(我的客戶端實際上是神經節的守護進程gmond的一個實例)。這是客戶端的代碼:

def getMessage(self): 

    def timeoutHandler(signum, frame): 
     raise Exceptions.BFException('Timeout %d s lasted' % defaultTimeout) 

    self._client = None 
    msg = None 

    # To be sure that will not freeze, we set a signal 
    signal.signal(signal.SIGALRM, timeoutHandler) 
    signal.alarm(defaultTimeout) 

    try: 
     self._client = xmlrpclib.ServerProxy('http://192.168.0.57:49007') 
     msg = self._client.reportAll() 
    except: 
     print 'The connection has not been established' 
     self._client = None 
     msg = None 
    finally: 
     signal.alarm(0) 
     return msg 

但是無論我做什麼,有時它完全凍結,我得到這個錯誤:

Exception happened during processing of request from ('192.168.0.85', 55417) 
Traceback (most recent call last): 
    File "C:\Python26\lib\SocketServer.py", line 283, in _handle_request_noblock 
    self.process_request(request, client_address) 
    File "C:\Python26\lib\SocketServer.py", line 309, in process_request 
    self.finish_request(request, client_address) 
    File "C:\Python26\lib\SocketServer.py", line 322, in finish_request 
    self.RequestHandlerClass(request, client_address, self) 
    File "C:\Python26\lib\SocketServer.py", line 617, in __init__ 
    self.handle() 
    File "C:\Python26\lib\BaseHTTPServer.py", line 329, in handle 
    self.handle_one_request() 
    File "C:\Python26\lib\BaseHTTPServer.py", line 323, in handle_one_request 
    method() 
    File "C:\Python26\lib\SimpleXMLRPCServer.py", line 491, in do_POST 
    self.wfile.write(response) 
    File "C:\Python26\lib\socket.py", line 318, in write 
    self.flush() 
    File "C:\Python26\lib\socket.py", line 297, in flush 
    self._sock.sendall(buffer(data, write_offset, buffer_size)) 
error: [Errno 10053] Une connexion établie a été abandonnée par un logiciel de votre ordinateur hôte 

如果我做同樣的Debian發行版,我得到的同樣的錯誤除了我得到:[Errno 32]破管

而且無論我做什麼,如果呼叫此再次服務器我總是得到這個錯誤得到一個第一次出現此錯誤後,並沒有任何反應都沒有。 我不知道該如何處理。我一直卡住上幾天......

誰能幫幫我好嗎?

感謝

回答

0

基本上你是殺了客戶端的連接,所以服務器報告連接已經終止。

我不知道爲什麼你得到後一點反應都沒有,但有一點要考慮的是,該服務器是單線程的,因此而慢操作正在進行的其它連接都可以加工。

此外請注意,信號可能不會傳送到signal()的調用相同的線程,這樣可能會導致您的問題,除非python在幕後做了一些魔術,以確保通知正確的線程。同樣,我不確定拋出一個異常是否被普遍允許,當然,從C來說,你不應該指望永遠在主堆棧上。

0

爲什麼不運行客戶機上的simpleXMLRPC服務器以及與輔助線程和隊列實現您的原始服務器。您的原始服務器會將參數推送至隊列並立即返回。工作線程在隊列上等待並在數據可用時執行。完成後,它將數據作爲參數發送回客戶端,與接收來自客戶端的呼叫完全相同。

這樣做,這樣意味着,無論是客戶端還是服務器將阻止。