16.1 测试链接属性
我们在基于lars_reactor开发的时候,可能有时候需要在写消息回调的时候,希望conn绑定一些属性。现在我们可以配置这种功能到`net_connection`上。
lars_reactor/include/net_connection.h
#pragma once#include <stdio.h>/*** 网络通信的抽象类,任何需要进行收发消息的模块,都可以实现该类** */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 <string>#include <string.h>#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 <stdio.h>#include <string.h>//客户端业务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无任何改变。
运行结果
- 服务端:
$ ./servermsg_router init...ip = 127.0.0.1, port = 7777create 0 threadcreate 1 threadcreate 2 threadcreate 3 threadcreate 4 threadadd msg cb msgid = 1add msg cb msgid = 2begin acceptbegin accept[thread]: get new connection succ!callback_busi ...conn param = I am the conn for you!
会发现我们是可以在callback中拿到conn的属性
