网游服务器大多提供了网关服务用于作为用户和内部服务器组之间通信代理网关服务一方面将用户消息从客户端分发到正确的内部服务器 另一方面将来自内部服务器的数据包转发给客户端一般对于网关应用来说压力最大的就是广播服务一个用户的在游戏中产生的行为消息 可能要广播给周数百个能看得见他的其它玩家下面用kendynet编写一个简单的网关服务当然这只是一个示例程序它只是简单的把来自一 连接的数据发往另一个连接真实网络游戏中的网关服务要复杂得多 首先介绍一下基本设计 static msgdisp_t disp_to_server; static msgdisp_t disp_to_client; sock_ident to_server; 首先定义两个消息处理器一个用户处理来自用的消息一个用于处理来自内部服务器的消息 然后是一个sock_ident用于表示与内部服务器的连接 接着在main函数中: asynnet_t asynet = asynnet_new();//个poller个用于监听个用于处理客户端连接个用于处理服务器连接 msgdisp_t disp_to_server = new_msgdisp(asynet to_server_connect to_server_connected NULL to_server_process NULL); msgdisp_t disp_to_client = new_msgdisp(asynet to_client_connect NULL NULL to_client_process NULL); thread_t service = create_thread(THREAD_JOINABLE); thread_t service = create_thread(THREAD_JOINABLE); to_client_ip = argv[]; to_client_port = atoi(argv[]); to_server_ip = argv[]; to_server_port = atoi(argv[]); thread_start_run(serviceservice_toserver(void*)disp_to_server); sleepms(); thread_start_run(serviceservice_toclient(void*)disp_to_client); 先创建一个异步网络引擎传入参数表示创建个poller其中第个用于处理监听套接口第个用于处于与内部服务器 的连接第个用户处理和客户端的连接 接着用不同的消息回调函数创建两个消息服务 最后创建两个单独的线程分别运行两个消息服务 接着再来看一下回调服务的处理: void to_server_connected(msgdisp_t dispsock_ident sockconst char *ipint_t portuint_t err) { to_server = sock; } int_t to_client_process(msgdisp_t dispsock_ident sockrpacket_t rpk) { if(!eq_sockident(sockto_server)){ //from clietsend to server push_msg(disp_to_server(msg_t)rpk); }else { //from serversend to client sock_ident client = read_from_rpacket(rpk); asyn_send(clientwpk_create_by_other((struct packet*)rpk)); } return ; } void to_client_connect(msgdisp_t dispsock_ident sockconst char *ipint_t port) { //用第个poller处理到客户端的连接 disp>bind(dispsock*); } int_t to_server_process(msgdisp_t dispsock_ident sockrpacket_t rpk) { if(!eq_sockident(sockto_server)){ //from clietsend to server asyn_send(to_serverwpk_create_by_other((struct packet*)rpk)); }else{ //from serversend to client push_msg(disp_to_client(msg_t)rpk); } return ; } void to_server_connect(msgdisp_t dispsock_ident sockconst char *ipint_t port) { //用第二个poller处理到服务器的连接 disp>bind(dispsock*); } 首先注意两个connect回调对于server绑定到号poller对于client绑定到号poller 然后再看两个process函数对于client的process函数来说如果发现发包的套接口不是to_server就将数据包 投递给disp_to_server由disp_to_server将这个数据包发送给内部服务如果发现数据包是来自to_server 那么就从数据包中读出发送目标然后将数据包发送给目标客户端 server的process函数则正好相反将来自to_server的消息投递给disp_to_client将来自客户端的消息从to_server 发送出去一个简单的消息转发服务就这样实现了 完整的示例程序可以参看: |