遊戲伺服器之被動連線線程池

2021-06-21 15:30:19 字數 4230 閱讀 4489

本文內容是遊戲伺服器之被動連線線程池。顧名思義,被動連線線程池處理的是被動連線的會話的狀態管理和資料收發。

設計上:

每個伺服器物件有個接收連線線程池, 執行緒型別包括:

驗證執行緒、同步執行緒、網路接收傳送執行緒、**執行緒。

會話正常流程步驟(正常狀態切換流程):

(1)程式主線程接收連線(監聽連線)

(2)驗證執行緒(檢查驗證超時、驗證發來訊息的伺服器id和伺服器ip(伺服器之間,依靠中心伺服器發來的依賴伺服器列表)、驗證賬號和臨時id和賬號(客戶端登陸和重登陸))

(3)同步執行緒(閘道器發訊息刪除中心伺服器登陸會話,中心伺服器讀資料庫檢查其他伺服器連線的合法性、傳送測試訊息到對端)

(4)網路接收傳送執行緒

(5)**執行緒(**連線)

1、被動連線線程池初始化

2、被動連線池的會話管理

(1)未使用會話到驗證執行緒

(2)驗證會話到同步執行緒

(3)會話到**執行緒

3、網路資料收發

(1)處理網路讀

(1-1)建立讀epoll描述符

(1-2)遍歷所有連線

(1-3)檢查讀事件

(1-4)**需要斷開的連線

(1-5)新增需要讀的連線到epoll描述符

(1-6)處理epoll讀事件(非阻塞檢查)

(1-7)接收有讀事件的連線的資料

(2)處理網路寫

(2-1)成功接收到資料才檢查寫快取(連線的寫事件一直存在)

(2-2)每隔一段時間才檢查寫快取

(2-3)檢查epoll描述符(kdpfd)有事件的連線(寫事件一直存在)

(2-4)再次是否有讀事件(epoll描述符kdpfd)

(2-5)連線的接收資料

(2-6)檢查連線的寫事件(連線的寫事件一直存在,目的檢查的是寫快取)

(2-6)連線寫資料

(3)程序關閉前**所有的會話

4、伺服器關閉銷毀資源

1、被動連線線程池初始化

初始化是在程序主線程的伺服器物件(具體伺服器類物件)的初始化函式裡。

執行緒型別包括:**執行緒、驗證執行緒、同步執行緒、網路接收傳送執行緒(網路接收傳送執行緒也是根據配置有多個)。

執行緒池初始化

bool tcp_session_pool::init()

//建立初始化驗證執行緒

if(!verifythreads.init(1,8,"verify_thread",this))//檢查驗證超時、中心伺服器的伺服器配置驗證(讀資料庫)

//建立初始化同步執行緒

if(!syncthreads.init(1,1,"sync_thread",this))

//建立初始網路接收傳送執行緒(這裡的網路接收傳送執行緒只是處理網路接收和傳送的執行緒)

int maxthreadcount = (maxconns + main_service_thread::getmaxsize() - 1)/main_service_thread::getmaxsize();

g_log->debug("執行緒最大連線數%d,每執行緒連線數%d,執行緒個數%d",maxconns,main_service_thread::getmaxsize(),maxthreadcount);

if(!okaythreads.init(1,maxthreadcount,"main_service_thread",this))

return true;

}2、被動連線池的會話管理

連線的狀態處理是由執行緒池的那些狀態管理執行緒來處理的,連線的狀態會進行轉換,把連線物件交給其他執行緒來管理。

(1)未使用會話到驗證執行緒

bool tcp_session_pool::addverify(tcp_session *task)

else

return true;

}(2)驗證會話到同步執行緒

void tcp_session_pool::addsync(tcp_session *task)

else

}(2)同步會話到網路收發執行緒

bool tcp_session_pool::addokay(tcp_session *task)

g_log->fatal("沒有找到主線程新增任務");

//沒有找到執行緒來處理這個連線,需要**關閉連線

return false;

}(3)會話到**執行緒

void tcp_session_pool::addrecycle(tcp_session *task)

else

}3、網路資料收發

網路收發執行緒的迴圈部分,處理網路資料的接收和傳送。

網路的處理是讀優先的,有讀才檢查寫,寫的檢查是一段時間檢查一次。

有個讀epoll描述符來處理網路資料的接收。

void main_service_thread::run()

task->delepoll(kdpfd, epollin | epollout | epollerr | epollpri);

task->msocket.changesocket(0);

if (task->isfdsradd())

task->addepoll(kdpfd, epollin | epollout | epollerr | epollpri, (void *)task);//kdpfd 裡面一直有所有的連線

}//檢查測試訊號指令(檢查是否需要傳送網路測試訊號(只有簡單包頭的沒有內容的訊息)到客戶端)

task->checksignal(currenttime);

(1-4)**需要斷開的連線

if (task->isterminatewait())//檢查任務是否被中斷,是的話就要設定中斷任務標識

if (task->isterminate())//如果連線被中斷就從epoll中刪除(從epoll描述符中刪除掉對該套接字的監聽),並**該連線

remove(it);

task->getnextstate();//先設定狀態再新增容器

pool->addrecycle(task);

}else

}++it;}}

}check=false;

}thread_base::msleep(2);

(1-6)處理epoll讀事件(非阻塞檢查)

if(fds_count_r)//處理epoll讀事件

else

task->delepoll(kdpfd, epollin | epollout | epollerr | epollpri);}}

else}}

epfds_r[i].events=0;}}

}(2)處理網路寫

(2-1)成功接收到資料才檢查寫快取(連線的寫事件一直存在)

if(check)//套接字出錯或者有讀事件但還沒到讀緩衝區則繼續讀下乙個,否則開始檢查寫快取(連線的寫事件一直存在)

(2-2)每隔一段時間才檢查寫快取

//每隔一段時間才檢視檢查是否有寫事件需要處理

if (currenttime.msec() - _write_time.msec() >= (unsigned long)(pool->usleep_time/1000))

else

task->delepoll(kdpfd, epollin | epollout | epollerr | epollpri);}}

else

}(2-6)檢查連線的寫事件(連線的寫事件一直存在,目的檢查的是寫快取)

if (epfds[i].events & epollout)//處理寫事件}}

epfds[i].events=0;//該事件處理完後去掉該標識}}

}check=true;}}

(3)程序關閉前**所有的會話

**所有的會話:

//執行緒關閉後就先要加入**佇列先把所有的任務**掉

//把所有任務佇列中的連線加入到**佇列中,**這些連線

for(it = tasks.begin(); it != tasks.end();)

temp_failure_retry(::close(kdpfd_r));//關閉epoll描述符

}4、伺服器關閉銷毀資源

server_base::~server_base()

//關閉epoll控制代碼

temp_failure_retry(::close(epoll_handler));

if (-1 != sock_handler) 

}連線池刪除時需要關閉所有這些執行緒

void tcp_session_pool::final()

**:

遊戲伺服器設計之任務系統

任務系統是遊戲中最重要的系統之一,本文旨在設計乙個輕量清晰的任務系統。通用易擴充套件是本系統關注的重點。任務系統中當角色的條件滿足時,自動觸發每一型別的任務,每個任務有其所需的完成條件,當角色完成了指定的操作後,則會觸發任務自動完成,任務完成後一般玩家會領取對應的獎勵,結束任務,此任務的生命週期結束...

遊戲伺服器設計之NPC系統

npc系統是遊戲中非常重要的系統,設計的好壞很大程度上影響遊戲的體驗。npc在遊戲中有如下作用 引導玩家體驗遊戲內容,一般遊戲內有很多主線 支線任務,而任務的介紹 接取 領取獎勵等操作都是通過npc的操作,一般會有幾個核心npc,再不停的任務引導中,玩家會對核心npc印象深刻,強化了遊戲代入感。核心...

遊戲伺服器設計之屬性管理器

遊戲中角色擁有的屬性值很多,運營多年的遊戲,往往會有很多個成長線,每個屬性都有可能被n個成長線模組增減數值。舉例當角色戴上 時候hp 100點,卸下 時hp 100點,這樣加減邏輯只有一處還比較好控制,如果某天有個特殊功能當被某技能攻擊時,角色 會被擊落,這樣就會出現減數值的操作不止一處。如果邏輯處...