程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 使用kendynet編寫網關服務

使用kendynet編寫網關服務

編輯:關於.NET

網游服務器大多提供了網關服務,用於作為用戶和內部服務器組之間通信代理 .網關服務一方面將用戶消息從客戶端分發到正確的內部服務器.

另一方面將來自內部服務器的數據包轉發給客戶端.一般對於網關應用來說, 壓力最大的就是廣播服務。一個用戶的在游戲中產生的行為消息

可能要廣播給周數百個能看得見他的其它玩家.下面用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/gateser vice.c

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved