網游服務器大多提供了網關服務用於作為用戶和內部服務器組之間通信代理網關服務一方面將用戶消息從客戶端分發到正確的內部服務器
另一方面將來自內部服務器的數據包轉發給客戶端一般對於網關應用來說壓力最大的就是廣播服務一個用戶的在游戲中產生的行為消息
可能要廣播給周數百個能看得見他的其它玩家下面用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
發送出去一個簡單的消息轉發服務就這樣實現了
完整的示例程序可以參看:
From:http://tw.wingwit.com/Article/program/Web/201404/30642.html