2017-02-15 14 views
0

我正在繼承ReconnectingClientFactory並使用SSL連接。我們已經全部運行,但幾分鐘後我收到以下錯誤消息。一旦這個錯誤happend,連接丟失Twisted:混合使用SSL寫入重新連接客戶端工廠()時常提升ssl錯誤

Unhandled Error 
Traceback (most recent call last): 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/python/log.py", line 103, in callWithLogger 
    return callWithContext({"system": lp}, func, *args, **kw) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/python/log.py", line 86, in callWithContext 
    return context.call({ILogContext: newCtx}, func, *args, **kw) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext 
    return self.currentContext().callWithContext(ctx, func, *args, **kw) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext 
    return func(*args,**kw) 
--- <exception caught here> --- 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/internet/posixbase.py", line 597, in _doReadOrWrite 
    why = selectable.doRead() 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/internet/tcp.py", line 208, in doRead 
    return self._dataReceived(data) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/internet/tcp.py", line 214, in _dataReceived 
    rval = self.protocol.dataReceived(data) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/protocols/tls.py", line 430, in dataReceived 
    self._flushReceiveBIO() 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/protocols/tls.py", line 400, in _flushReceiveBIO 
    self._flushSendBIO() 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/twisted/protocols/tls.py", line 352, in _flushSendBIO 
    bytes = self._tlsConnection.bio_read(2 ** 15) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/OpenSSL/SSL.py", line 1384, in bio_read 
    self._handle_bio_errors(self._from_ssl, result) 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/OpenSSL/SSL.py", line 1365, in _handle_bio_errors 
    _raise_current_error() 
    File "/usr/local/hikvision/ezops/python/lib/python2.7/site-packages/OpenSSL/_util.py", line 48, in exception_from_error_queue 
    raise exception_type(errors) 
OpenSSL.SSL.Error: [] 

我的客戶端代碼:

reactor.connectSSL(opscenter_addr, int(opscenter_port), NoahAgentFactory(), ssl.ClientContextFactory()) 

類NoahAgentFactory這樣的:

import logging 
import traceback 

from OpenSSL import SSL 
from twisted.internet import reactor,ssl 
from twisted.internet import task 
from twisted.internet.protocol import Protocol 
from twisted.internet.protocol import ReconnectingClientFactory 
import DataPackageCodecFactory as Codec 
from Header import MessageHandlerMap 
from Handler import HBReq, DefaultRspHandler 
from Util import Connection 

logger = logging.getLogger('opsagent') 


class NoahAgentProtocol(Protocol): 
    t = None 
    def connectionMade(self): 
     ''' 
      客戶端連接成功之後會自動調用該方法 
      :return: 
     ''' 
     self.transport.setTcpKeepAlive(True) # maintain the TCP connection 
     self.transport.setTcpNoDelay(True) # allow Nagle algorithm 

     # 連接成功後保存連接信息 
     Connection.AgentTcpConnection = self 
     global t 
     logger.info('is already connect to the server') 
     self.recv_data_buffer = '' 
     # 創建定時的心跳任務,每隔30秒執行一次 
     t = task.LoopingCall(HBReq.execute, *[self]) 
     t.start(30) 

    def dataReceived(self, data): 
     logger.debug("Received Message: %s", repr(data)) 
     ###code handler packages########## 

    def connectionLost(self, reason): 
     ''' 
     當客戶端連接斷開的時候,會自動調用該方法 
     :param reason: 
     :return: 
     ''' 
     try: 
      t.stop() 
      # 清空全局鏈接信息 
      Connection.AgentTcpConnection = None 
     except: 
      logger.error(traceback.format_exc()) 
     logger.info('Connection is lost and Task stopped,Resaon =>%s', reason) 


class NoahAgentFactory(ReconnectingClientFactory): 
    def startedConnecting(self, connector): 
     logger.info('Started to connect.') 

    def buildProtocol(self, addr): 
     logger.info('Connected.') 
     logger.info('Resetting reconnection delay') 
     self.resetDelay() 
     return NoahAgentProtocol() 

    def clientConnectionLost(self, connector, reason): 
     logger.info('Lost connection. Reason:%s', reason) 
     self.resetDelay() 
     self.retry(connector) 
     # ReconnectingClientFactory.clientConnectionLost(self, connector, reason) 

    def clientConnectionFailed(self, connector, reason): 
     logger.info('Connection failed. Reason:%s', reason) 
     self.resetDelay() 
     self.retry(connector) 
+0

看來這可能是Twisted的TLS支持中的一個錯誤。很高興知道:Python的版本,Twisted的版本,OpenSSL的版本,加密的版本,pyOpenSSL的版本,以及此連接另一端運行的內容(公共TLS服務器,另一端你寫的服務器,它使用的TLS實現等)。如果有一個能夠再現問題的最簡單的例子,它也會非常好。 http://sscce.org/ –

回答

0

我想是不是在扭曲的一個bug TLS以外的錯誤,我發送消息不在主反應器線程中,因爲我們知道,twisted是單線程模式,所以不需要考慮線程安全問題。但是我使用reactor.callInThread來處理long tim e直接發送消息併發送消息,並且write()不是線程安全的,所以調用該錯誤,一旦我在發送消息上使用reactor.callFromThread,它就會正常運行。