zoukankan      html  css  js  c++  java
  • 使用kendynet编写网关服务

    网游服务器大多提供了网关服务,用于作为用户和内部服务器组之间通信代理.网关服务一方面将用户消息从客户端分发到正确的内部服务器.

    另一方面将来自内部服务器的数据包转发给客户端.一般对于网关应用来说,压力最大的就是广播服务。一个用户的在游戏中产生的行为消息

    可能要广播给周数百个能看得见他的其它玩家.下面用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(3);//3个poller,1个用于监听,1个用于处理客户端连接,1个用于处理服务器连接
        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 service1 = create_thread(THREAD_JOINABLE);
        thread_t service2 = create_thread(THREAD_JOINABLE);
    
        to_client_ip = argv[1];
        to_client_port = atoi(argv[2]);
    
    
        to_server_ip = argv[3];
        to_server_port = atoi(argv[4]);
    
        thread_start_run(service1,service_toserver,(void*)disp_to_server);
        sleepms(1000);
        thread_start_run(service2,service_toclient,(void*)disp_to_client);

    先创建一个异步网络引擎,传入参数3,表示创建3个poller,其中第1个用于处理监听套接口,第2个用于处于与内部服务器

    的连接,第3个用户处理和客户端的连接.

    接着用不同的消息回调函数创建两个消息服务.

    最后创建两个单独的线程分别运行两个消息服务.

    接着再来看一下回调服务的处理:

    void to_server_connected(msgdisp_t disp,sock_ident sock,const char *ip,int32_t port,uint32_t err)
    {
        to_server = sock;
    }
    
    
    int32_t to_client_process(msgdisp_t disp,sock_ident sock,rpacket_t rpk)
    {
        if(!eq_sockident(sock,to_server)){
            //from cliet,send to server
            push_msg(disp_to_server,(msg_t)rpk);
        }else
        {
            //from server,send to client
            sock_ident client = read_from_rpacket(rpk);
            asyn_send(client,wpk_create_by_other((struct packet*)rpk));
        }
        return 1;
    }
    
    void to_client_connect(msgdisp_t disp,sock_ident sock,const char *ip,int32_t port)
    {
        //用第3个poller处理到客户端的连接
        disp->bind(disp,3,sock,1,3*1000,0);
    }
    
    
    int32_t to_server_process(msgdisp_t disp,sock_ident sock,rpacket_t rpk)
    {
        if(!eq_sockident(sock,to_server)){
            //from cliet,send to server
            asyn_send(to_server,wpk_create_by_other((struct packet*)rpk));
        }else{
            //from server,send to client
            push_msg(disp_to_client,(msg_t)rpk);
        }
        return 1;
    }
    
    void to_server_connect(msgdisp_t disp,sock_ident sock,const char *ip,int32_t port)
    {
        //用第二个poller处理到服务器的连接
        disp->bind(disp,2,sock,1,3*1000,0);
    }

    首先注意两个connect回调,对于server绑定到2号poller,对于client绑定到3号poller.

    然后再看两个process函数.对于client的process函数来说,如果发现发包的套接口不是to_server,就将数据包

    投递给disp_to_server,由disp_to_server将这个数据包发送给内部服务.如果发现数据包是来自to_server,

    那么就从数据包中读出发送目标,然后将数据包发送给目标客户端.

    server的process函数则正好相反,将来自to_server的消息投递给disp_to_client.将来自客户端的消息从to_server

    发送出去.一个简单的消息转发服务就这样实现了。

    完整的示例程序可以参看:

    https://github.com/sniperHW/luanet/blob/master/kendynet/test/gateservice.c

  • 相关阅读:
    jmeter(46) redis
    jmeter(45) tcp/ip协议
    Codeforces Round #538 (Div. 2)D(区间DP,思维)
    Codeforces Global Round 1D(DP,思维)
    Educational Codeforces Round 57D(DP,思维)
    UPC11073(DP,思维)
    Yahoo Progamming Contest 2019D(DP,思维)
    Atcoder Beginner Contest 118D(DP,完全背包,贪心)
    Xuzhou Winter Camp 1C(模拟)
    Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
  • 原文地址:https://www.cnblogs.com/sniperHW/p/3519379.html
Copyright © 2011-2022 走看看