This time we’ll focus on the callback mechanism used extensively in the Muduo library. Muduo mainly uses Callback to implement callbacks, starting with a few lines of code in our EchoServer constructor

    EchoServer(EventLoop *loop,
            const InetAddress &addr, 
            const std::string &name)
        : server_(loop, addr, name)
        , loop_(loop)
    {
        // Register the callback function
        server_.setConnectionCallback(
            std::bind(&EchoServer::onConnection, this, std::placeholders::_1)
        );

        server_.setMessageCallback(
            std::bind(&EchoServer::onMessage, this,
                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
        );

        // Set an appropriate number of loopthreads
        server_.setThreadNum(3);
    }
Copy the code

Using setConnectionCallback and setMessageCallback, let’s see how TcpServer implements setConnectionCallback

void setConnectionCallback(const ConnectionCallback &cb) { connectionCallback_ = cb; }
Copy the code

EchoServer::onConnection will be executed when a new connection is established. We set a callback function for the TcpServer, and when the Acceptor in the TcpServer accepts a new connection, The TcpServer will set up a new TcpConnection with this connfd and the corresponding peerAddr, and the TcpServer will set a callback to the TcpConnection, and this callback is the callback we set for the TcpServer

    // Create a TcpConnection based on the sockfd successfully connected
    TcpConnectionPtr conn(new TcpConnection(
                            ioLoop,
                            connName,
                            sockfd,   // Socket Channel
                            localAddr,
                            peerAddr));
    connections_[connName] = conn;
	The following callback is set by the user to the TcpServer, which is set by the TcpConnection, which is set by the TcpConnetion, which is set by the Channel, which is set by the Poller, which tells the Channel to invoke the callback
    conn->setConnectionCallback(connectionCallback_);
    conn->setMessageCallback(messageCallback_);
    conn->setWriteCompleteCallback(writeCompleteCallback_);
Copy the code

Conn ->setMessageCallback(messageCallback_) when a new message comes from an established connection; This line of code indicates that we have set up a callback for conn when a message comes in. Let’s see how TcpConnection handles setMessageCallback

    void setConnectionCallback(const ConnectionCallback& cb)
    { connectionCallback_ = cb; }
Copy the code

So when a message arrives, the callback we set up, onMessage, will be executed. At this point we have a basic idea of what to do when a new connection is established and when a message arrives for an old connection. In the next chapter we will look at the Buffer classes that are sent between messages.