首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

使用 kendynet 編寫高效網關服務:架構與核心代碼解析

     編輯:關於.NET

網遊伺服器常部署網關服務,作為客戶端與內部叢集的通訊代理:將客戶端訊息分發至正確的內部伺服器,並將內部回應轉發給客戶端。廣播服務是網關最大的壓力來源——單一玩家的行為可能需廣播給數百名可見玩家。本文示範用 kendynet 實作簡易網關,僅做訊息轉發演示,實際生產環境會更複雜。

核心設計

static msgdisp_t disp_to_server;
static msgdisp_t disp_to_client;
sock_ident to_server;

定義兩個訊息處理器:disp_to_client 處理來自客戶端的訊息,disp_to_server 處理來自內部伺服器的訊息;to_server 代表與內部伺服器的連線識別碼。

主流程

asynnet_t asynet = asynnet_new(3); // 3 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 service1 = create_thread(THREAD_JOINABLE);
thread_t service2 = create_thread(THREAD_JOINABLE);
// ... 設定 IP/port ...
thread_start_run(service1, service_toserver, (void*)disp_to_server);
sleepms(1000);
thread_start_run(service2, service_toclient, (void*)disp_to_client);

建立非同步網路引擎(3 個 poller),分別綁定不同連線類型的回呼,最後啟動兩條執行緒並行處理。

關鍵回呼實作

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)) {
        push_msg(disp_to_server, (msg_t)rpk); // 客戶端→伺服器
    } else {
        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) {
    disp->bind(disp, 3, sock, 1, 3*1000, 0); // 綁定第 3 poller
}
int32_t to_server_process(msgdisp_t disp, sock_ident sock, rpacket_t rpk) {
    if (!eq_sockident(sock, to_server)) {
        asyn_send(to_server, wpk_create_by_other((struct packet*)rpk)); // 客戶端→伺服器
    } else {
        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) {
    disp->bind(disp, 2, sock, 1, 3*1000, 0); // 綁定第 2 poller
}

連線建立時綁定對應 poller;處理函式根據來源套接字決定轉發方向,實現雙向透傳。

完整範例參考:GitHub 原始碼

作者:玄魂
出處:https://www.cnblogs.com/xuanhun/

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved