【Lars教程目录】
Lars源代码
https://github.com/aceld/Lars
【Lars系统概述】
第1章-概述
第2章-项目目录构建
【Lars系统之Reactor模型服务器框架模块】
第1章-项目结构与V0.1雏形
第2章-内存管理与Buffer封装
第3章-事件触发EventLoop
第4章-链接与消息封装
第5章-Client客户端模型
第6章-连接管理及限制
第7章-消息业务路由分发机制
第8章-链接创建/销毁Hook机制
第9章-消息任务队列与线程池
第10章-配置文件读写功能
第11章-udp服务与客户端
第12章-数据传输协议protocol buffer
第13章-QPS性能测试
第14章-异步消息任务机制
第15章-链接属性设置功能
【Lars系统之DNSService模块】
第1章-Lars-dns简介
第2章-数据库创建
第3章-项目目录结构及环境构建
第4章-Route结构的定义
第5章-获取Route信息
第6章-Route订阅模式
第7章-Backend Thread实时监控
【Lars系统之Report Service模块】
第1章-项目概述-数据表及proto3协议定义
第2章-获取report上报数据
第3章-存储线程池及消息队列
【Lars系统之LoadBalance Agent模块】
第1章-项目概述及构建
第2章-主模块业务结构搭建
第3章-Report与Dns Client设计与实现
第4章-负载均衡模块基础设计
第5章-负载均衡获取Host主机信息API
第6章-负载均衡上报Host主机信息API
第7章-过期窗口清理与过载超时(V0.5)
第8章-定期拉取最新路由信息(V0.6)
第9章-负载均衡获取Route信息API(0.7)
第10章-API初始化接口(V0.8)
第11章-Lars Agent性能测试工具
第12章- Lars启动工具脚本
16) 链接属性设置功能
16.1 测试链接属性
我们在基于lars_reactor开发的时候,可能有时候需要在写消息回调的时候,希望conn绑定一些属性。现在我们可以配置这种功能到net_connection
上。
lars_reactor/include/net_connection.h
#pragma once
#include
/*
*
* 网络通信的抽象类,任何需要进行收发消息的模块,都可以实现该类
*
* */
class net_connection
{
public:
net_connection():param(NULL) {}
//发送消息的接口
virtual int send_message(const char *data, int datalen, int msgid) = 0;
virtual int get_fd() = 0;
void *param; //TCP客户端可以 通过该参数传递一些自定义的参数
};
//创建链接/销毁链接 要触发的 回调函数类型
typedef void (*conn_callback)(net_connection *conn, void *args);
这里我们给net_connection
类添加了一个param
属性,这样,我们就可以绑定一些开发者自定义的参数和当前链接进行绑定。注意,这里也提供了一个get_fd()
的纯虚函数,目的是提供conn获取当前fd的数据。
16.2 完成Lars Reactor V0.12开发
server端
#include "tcp_server.h"
#include
#include
#include "config_file.h"
tcp_server *server;
//回显业务的回调函数
void callback_busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data)
{
printf("callback_busi ...\n");
//直接回显
conn->send_message(data, len, msgid);
printf("conn param = %s\n", (const char *)conn->param);
}
//打印信息回调函数
void print_busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data)
{
printf("recv client: [%s]\n", data);
printf("msgid: [%d]\n", msgid);
printf("len: [%d]\n", len);
}
//新客户端创建的回调
void on_client_build(net_connection *conn, void *args)
{
int msgid = 101;
const char *msg = "welcome! you online..";
conn->send_message(msg, strlen(msg), msgid);
//将当前的net_connection 绑定一个自定义参数,供我们开发者使用
const char *conn_param_test = "I am the conn for you!";
conn->param = (void*)conn_param_test;
}
//客户端销毁的回调
void on_client_lost(net_connection *conn, void *args)
{
printf("connection is lost !\n");
}
int main()
{
event_loop loop;
//加载配置文件
config_file::setPath("./serv.conf");
std::string ip = config_file::instance()->GetString("reactor", "ip", "0.0.0.0");
short port = config_file::instance()->GetNumber("reactor", "port", 8888);
printf("ip = %s, port = %d\n", ip.c_str(), port);
server = new tcp_server(&loop, ip.c_str(), port);
//注册消息业务路由
server->add_msg_router(1, callback_busi);
server->add_msg_router(2, print_busi);
//注册链接hook回调
server->set_conn_start(on_client_build);
server->set_conn_close(on_client_lost);
loop.event_process();
return 0;
}
我们在 on_client_build
中,对创建链接做了conn的参数传递,然后通过路由业务的转发,我们在callback_busi
中,得到了之前传递进去的参数。这样对我们使用框架做一些复杂的业务,需要绑定一些属性给conn是有必要的。
client端
#include "tcp_client.h"
#include
#include
//客户端业务
void busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data)
{
//得到服务端回执的数据
char *str = NULL;
str = (char*)malloc(len+1);
memset(str, 0, len+1);
memcpy(str, data, len);
printf("recv server: [%s]\n", str);
printf("msgid: [%d]\n", msgid);
printf("len: [%d]\n", len);
}
//客户端销毁的回调
void on_client_build(net_connection *conn, void *args)
{
int msgid = 1;
const char *msg = "Hello Lars!";
conn->send_message(msg, strlen(msg), msgid);
}
//客户端销毁的回调
void on_client_lost(net_connection *conn, void *args)
{
printf("on_client_lost...\n");
printf("Client is lost!\n");
}
int main()
{
event_loop loop;
//创建tcp客户端
tcp_client client(&loop, "127.0.0.1", 7777, "clientv0.6");
//注册消息路由业务
client.add_msg_router(1, busi);
client.add_msg_router(101, busi);
//设置hook函数
client.set_conn_start(on_client_build);
client.set_conn_close(on_client_lost);
//开启事件监听
loop.event_process();
return 0;
}
和之前的client无任何改变。
运行结果
- 服务端:
$ ./server
msg_router init...
ip = 127.0.0.1, port = 7777
create 0 thread
create 1 thread
create 2 thread
create 3 thread
create 4 thread
add msg cb msgid = 1
add msg cb msgid = 2
begin accept
begin accept
[thread]: get new connection succ!
callback_busi ...
conn param = I am the conn for you!
会发现我们是可以在callback中拿到conn的属性
关于作者:
作者:Aceld(刘丹冰)
mail: [email protected]
github: https://github.com/aceld
原创书籍gitbook: http://legacy.gitbook.com/@aceld
原创声明:未经作者允许请勿转载, 如果转载请注明出处