分布式网络通信框架-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框架的业务代码。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注