Exemple #1
0
 def setCrypter(self, encrypter, decrypter):
     if self.encrypted or self.compressed:
         self.connector.setCrypter(encrypter, decrypter)
     else:
         self.connector = CryptCompressConnector(self.connector, encrypter, decrypter)
     self.encrypted = True
Exemple #2
0
 def setCompressor(self, compressor):
     if self.encrypted or self.compressed:
         self.connector.setCompressor(compressor)
     else:
         self.connector = CryptCompressConnector(self.connector, None, None, compressor)
     self.compressed = True
Exemple #3
0
class RpcChannel(service.RpcChannel):
    """序列化与反序列化rpc调用,内部封装一个底层连接(TcpConnector)"""

    def __init__(self, rpcService, connector):
        super(RpcChannel, self).__init__()

        self.rpcService = rpcService # 将rpc请求传递给上层
        self.rpcRequest = MarsRequest.Request() # rpc请求的解析
        self.rpcRequestParser = MarsRequest.RequestParser()
        self.connector = connector # 底层网络连接
        self.connector.setChannelObj(self)
        self.controller = RpcController(self) # 传递channel给上层
        self.listeners = set()

        self.logger = LogManager.getLogger('MarsRpc.RpcChannel')
        self.logger.info('RpcChannel.__init__: an new connection')

        # user data
        self.userData = None
        self.encrypted = False
        self.compressed = False
        self.sessionSeed = None

    def setMaxDataBytes(self, maxBytes):
        self.rpcRequestParser.setMaxDataBytes(maxBytes)

    def regListener(self, listener):
        """注册listener"""
        self.logger.debug('RpcChannel.regListener')
        self.listeners.add(listener)

    def unregListener(self, listener):
        self.listeners.discard(listener)

    def getPeername(self):
        """返回对端的(ip, port)"""
        assert self.connector is not None, 'No connector attached'
        return self.connector.getPeername()

    def setCrypter(self, encrypter, decrypter):
        if self.encrypted or self.compressed:
            self.connector.setCrypter(encrypter, decrypter)
        else:
            self.connector = CryptCompressConnector(self.connector, encrypter, decrypter)
        self.encrypted = True

    def setCompressor(self, compressor):
        if self.encrypted or self.compressed:
            self.connector.setCompressor(compressor)
        else:
            self.connector = CryptCompressConnector(self.connector, None, None, compressor)
        self.compressed = True

    def setUserData(self, userData):
        self.userData = userData

    def getUserData(self):
        return self.userData

    def setSessioSeed(self, seed):
        self.sessionSeed = seed

    def getSessionSeed(self):
        return self.sessionSeed

    def disconnect(self):
        """断开连接"""
        self.connector and self.connector.disconnect()

    def CallMethod(self, methodDescriptor, rpcController, request, responseClass, done):
        """发送rpc调用"""
        cmdIndex = methodDescriptor.index
        assert cmdIndex < 65535
        data = request.SerializeToString()
        totalLen = len(data) + 2
        self.connector.writeData(''.join([pack('<I', totalLen), pack('<H', cmdIndex), data]))

    def onDisconnected(self):
        """底层连接断开时回调"""
        self.logger.info('onDisconnected')
        for listener in self.listeners:
            listener.onChannelDisconnected(self)
        self.rpcRequest.reset()
        self.rpcRequestParser.reset()
        self.listeners = None
        self.connector = None
        self.userData = None

    def onRead(self, data):
        totalLen = len(data)
        skil = 0
        while skip < totalLen:
            result, consumBytes = self.rpcRequestParser.parse(self.rpcRequest, data, skip)
            assert consumBytes > 0

            skip += consumBytes
            if result == 1:
                ok = self.onRequest()
                self.rpcRequest.reset()

                if not ok:
                    return 0
                continue
            elif result == 0:
                return 0
            elif result == 3:
                raise ProtobufLengthError('buffer length > MAX_DATA_BYTES')
            else:
                continue

        return 2

    def onRequest(self):
        """解析一个完整请求后的回调"""
        dataLen = len(self.rpcRequest.data)

        if dataLen < 2:
            self.logger.error('got error request size: %d', dataLen)
            return False

        indexData = self.rpcRequest.data[0:2]
        cmdIndex = unpack('<H', indexData)[0]

        rpcService = self.rpcService
        descriptor = rpcService.GetDescriptor()

        if cmdIndex > len(descriptor.methods):
            self.logger.error('got error method inex: %d', cmdIndex)
            return False

        method = descriptor.methods[cmdIndex]
        try:
            request = rpcService.GetRequestClass(method)()
            serialized = self.rpcRequest.data[2:]
            request.ParseFromString(serialized)
            rpcService.CallMethod(method, self.controller, request, None)
        except:
            self.logger.error('call rpc method failed')
            self.logger.logLastExcept()

        return True