分布式网络通信框架-rpc (四)Muduo网络库的使用
总纲
上一章介绍了如何使用protobuf,使用protobuf可以帮助我们进行参数的打包和拆包,借助protobuf提供的service,使用rpc关键字可以创建出服务类和相应的stub类,stub类即可作为代理类,所有的服务方法调用最终都由stub类中的CallMethod方法代为执行,详情请见上一章。(btw.今天去闵行给老板跑腿,地铁上无聊正巧看到硬核空间发的一篇硬核早餐——全图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架,里面的内容和思路都和本项目一致,其中有张图画的挺好,转过来看看)。

那么本章要介绍的就是如何利用网络的进行参数的传输了。本项目rpc服务提供端的网络传输使用的是Muduo网络库,因为在rpc服务端涉及高并发和多线程,muduo网络库可以帮助我们做到这些,在rpc服务请求端只是进行服务的请求和最终结果的接收不涉及高并发,因此使用socket编程来进行服务的请求和结果的接收(之前这里写到服务请求端使用socket模拟http短连接的说法是错误的,并且说它比较轻量也是不对的,详情,首先http本身是应用层协议,连接是传输层干的。其次socket本身是个系统接口他在进行网络连接时会使用tcp协议还是要进行连接的构建的,因此不存在说轻量不轻量,硬扯轻量的话只是编码上方便些)。再来介绍一下Muduo网络库,Muduo网络库是一个C++编写的高性能的网络库,由陈硕大佬编写,但是Muduo只能在Linux下使用。因此这里立个flag,过几天用libevent(在linux、maxos、windows上均可使用)把这个框架再实现一遍。
好了,本张就来介绍一下muduo库的使用,基操学会了,才能玩儿更多的东西。
介绍
Muduo库底层是依赖于epoll、linux下pthread库和boost库开发的,因此Muduo只能在linux环境中使用。
类似的c++网络库还有libevent。

muduo库的文件一般在/usr/lib或者/usr/local/lib路径中。
muduo库的使用需要链接 libmuduo_base.so libmuduo_net.so libpthread.so这三个动态链接库。
# 注意先写muduo_net,再写muduo_base,因为muduo_base也依赖于lmuduo_net
-lmuduo_net -lmuduo_base -lpthread
基本操作
muduo网络库给用户提供了两个主要的类:
– TcpServer : 用于编写服务器程序的
– TcpClient : 用于编写客户端程序的
基于muduo网络库开发服务器程序步骤
1. 组合TcpServer对象
2. 创建EventLoop事件循环对象的指针
3. 明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数
4. 在当前服务器类的构造函数当中,注册处理连接的回调函数和处理读写时间的回调函数
5. 设置合适的服务端线程数量,muduo库会自己分配I/O线程和worker线程
/*
muduo网络库给用户提供了两个主要的类
TcpServer : 用于编写服务器程序的
TcpClient : 用于编写客户端程序的
epoll + 线程池
好处:能够把网络I/O的代码和业务代码区分开
用户的连接和断开 用户的可读写事件
*/
#include <muduo/net/EventLoop.h>
#include <muduo/net/TcpServer.h>
#include <iostream>
#include <functional>
#include <string>
using namespace std;
using namespace muduo;
using namespace muduo::net;
using namespace placeholders;
/*
基于muduo网络库开发服务器程序 步骤
1.组合TcpServer对象
2.创建EventLoop事件循环对象的指针
3.明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数
4.在当前服务器类的构造函数当中,注册处理连接的回调函数和处理读写时间的回调函数
5.设置合适的服务端线程数量,muduo库会自己分配I/O线程和worker线程
*/
class ChatServer
{
public:
ChatServer(EventLoop *loop,
const InetAddress &listenAddr,
const string &nameArg)
: _server(loop, listenAddr, nameArg), _loop(loop)
{
// 给服务器注册用户连接的创建和断开回调
_server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));
//给服务器注册用户读写事件回调
_server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));
// 设置服务端线程数量 1个I/O线程,3个worker线程
_server.setThreadNum(4);
}
// 开启事件循环
void start()
{
_server.start();
}
private:
// 专门处理用户的连接和断开 epoll listenfd accept
void onConnection(const TcpConnectionPtr &conn)
{
}
// 专门处理用户的读写事件
void onMessage(const TcpConnectionPtr &conn, // 连接
Buffer *buffer, // 缓冲区
Timestamp time) // 接收到数据的时间信息
{
}
TcpServer _server; // #1
EventLoop *_loop; // #2 epoll
};
按照上面的常规操作,再编写好onConnection和onMessage两个响应函数就可以实现相应的操作了。
以上就是muduo库的基本使用。下一篇我们将从具体需求开始,逐步实现rpc框架的业务代码。