AMQP源码分析

rabbmtmq客户端入口方法:

private class MainLoop implements Runnable {
    @Override
    public void run() {
        boolean shouldDoFinalShutdown = true;
        try {
            while (_running) {
                Frame frame = _frameHandler.readFrame();
                readFrame(frame);
            }
        } catch (Throwable ex) {
            if (ex instanceof InterruptedException) {
                // loop has been interrupted during shutdown,
                // no need to do it again
                shouldDoFinalShutdown = false;
            } else {
                handleFailure(ex);
            }
        } finally {
            if (shouldDoFinalShutdown) {
                doFinalShutdown();
            }
        }
    }
}

 主要处理方法:

    private void readFrame(Frame frame) throws IOException {
        if (frame != null) {
            _missedHeartbeats = 0;
            if (frame.type == AMQP.FRAME_HEARTBEAT) {
                // Ignore it: we've already just reset the heartbeat counter.
            } else {
                if (frame.channel == 0) { // the special channel
                    _channel0.handleFrame(frame);
                } else {
                    if (isOpen()) {
                        // If we're still _running, but not isOpen(), then we
                        // must be quiescing, which means any inbound frames
                        // for non-zero channels (and any inbound commands on
                        // channel zero that aren't Connection.CloseOk) must
                        // be discarded.
                        ChannelManager cm = _channelManager;
                        if (cm != null) {
                            ChannelN channel;
                            try {
                                channel = cm.getChannel(frame.channel);
                            } catch(UnknownChannelException e) {
                                // this can happen if channel has been closed,
                                // but there was e.g. an in-flight delivery.
                                // just ignoring the frame to avoid closing the whole connection
                                LOGGER.info("Received a frame on an unknown channel, ignoring it");
                                return;
                            }
                            channel.handleFrame(frame);
                        }
                    }
                }
            }
        } else {
            // Socket timeout waiting for a frame.
            // Maybe missed heartbeat.
            handleSocketTimeout();
        }
    }

  

    public void handleFrame(Frame frame) throws IOException {
        AMQCommand command = _command;
        if (command.handleFrame(frame)) { // a complete command has rolled off the assembly line
            _command = new AMQCommand(); // prepare for the next one
            handleCompleteInboundCommand(command);
        }
    }

  

    public void handleCompleteInboundCommand(AMQCommand command) throws IOException {
        this._trafficListener.read(command);
        if (!processAsync(command)) {
            if (_checkRpcResponseType) {
                synchronized (_channelMutex) {
                    // check if this reply command is intended for the current waiting request before calling nextOutstandingRpc()
                    if (_activeRpc != null && !_activeRpc.canHandleReply(command)) {
                        // this reply command is not intended for the current waiting request
                        // most likely a previous request timed out and this command is the reply for that.
                        // Throw this reply command away so we don't stop the current request from waiting for its reply
                        return;
                    }
                }
            }
            final RpcWrapper nextOutstandingRpc = nextOutstandingRpc();
            // the outstanding RPC can be null when calling Channel#asyncRpc
            if(nextOutstandingRpc != null) {
                nextOutstandingRpc.complete(command);
                markRpcFinished();
            }
        }
    }

  

posted @ 2020-07-28 14:20  myTang  阅读(741)  评论(0)    收藏  举报