国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

一步一步開發Game服務器(二)完成登陸,聊天

2019-11-17 02:26:47
字體:
來源:轉載
供稿:網友

一步一步開發Game服務器(二)完成登陸,聊天

我知道這樣的文章在博客園已經多的大家都不想看了,但是這是我的系列文章開始,請各位大神見諒了。

多線程,線程執行器,(詳見),socket通信相關 (詳見)

本人blog相關文章測試代碼,示例,完整版svn地址。(http://code.taobao.org/svn/flynetwork_csharp/trunk/Flynetwork/BlogTest)

提供全部源碼功能塊。希望各位大神,提供寶貴意見。

莫倩,完成了多線程輔助類庫完整功能(或許后期會有bug需要修復或者優化),socket完成了tcp和http服務監聽功能,udp和websocket還在完善的狀態中。

如果有通信愿意和我一起完善這個輔助類庫,請聯系我,開通svn授權。

所以源碼免費提供使用,歡迎各位愛好者,加入到項目中,無論是個人,企業,商用,都不限制。唯一要求請保留以下字樣。謝謝合作~!

1 /**2  * 3  * @author 失足程序員4  * @Blog http://m.survivalescaperooms.com/ty408/5  * @mail 492794628@QQ.com6  * @phone 138821220197  * 8  */

好了開始我們的話題

在服務器項目開發中,最總要的也就是登陸問題了或者說叫授權問題。

我們先創建一個console的程序

引用我的兩個庫Sz.Network.SocketPool ,Sz.Network.ThreadPool 分別是socket 幫助庫線程幫助庫。

Sz表示失足的意思。請見諒。偶喜歡上這個代號了“失足程序員”

我們先創建一個消息處理器MessagePool

 1  public class MessagePool : ISocketPool 2     { 3         public void ActiveSocket(IOsession client) 4         { 5         } 6  7         public void CloseSocket(IOSession client) 8         { 9             10         }11 12         public void ReadMessage(IOSession client, SocketMessage message)13         {14             15         }16 17 18         public void ActiveHttp(HttpClient client, string bind, Dictionary<string, string> parms)19         {20             if (bind.Equals("/test/"))21             {22                 ThreadManager.GetInstance.AddTask(ServerManager.LoginThreadID, new LoginHttpHandler(client, parms));23             }24         }25 26         public void IOSessionException(IOSession client, Exception exception)27         {28             Logger.Error("內部錯誤", exception);29         }30 31         public void HttpException(HttpClient client, Exception exception)32         {33             Logger.Error("內部錯誤", exception);34         }35     }
View Code

然后在mian函數里面加入

1  Sz.Network.SocketPool.ListenersBox.GetInstance.SetParams(new MessagePool(), typeof(MarshalEndian));2             Sz.Network.SocketPool.ListenersBox.GetInstance.Start("tcp:*:9527", "http://*:8001/test/");

這樣我們就開啟了服務器的監聽,這里簡單介紹一下為什么我創建了tcp和http的兩個監聽呢?

這是因為經驗和工作關系,因為我是致力于游戲開發的,服務器端需要創建兩個tcp通常是用于正常通信的,而http監聽的登陸模塊,或者一些非總要性數據交換以及第三方登陸授權需要開啟的。同樣還因為http是短連接,無需保存通信對象,減少了系統消耗,和tcp數量級消耗。

如果你不理解可以不加入http的監聽的。直接看tcp的socket。

1 [2015-04-15 18:12:09:899:Info ] Start Listen Tcp Socket -> 0.0.0.0:95272 [2015-04-15 18:12:09:906:Info ] Start Listen Http Socket -> 0.0.0.0:8001/test/

運行程序,輸出。

開啟了tcp和http的監聽,http我們今天暫時忽略其作用吧。

我們開始準備登陸模塊的開發,同學都知道登陸首先要面臨的就是多點同時登陸問題。

如果加入 lock 來防止多點同時登陸,那么勢必照成服務器卡頓。吞吐量不高等因素。那么我們考慮把這一塊加入到單獨的線程驚喜處理。也就是幫登陸和登出,放到同一個線程處理。不用加鎖,也能做到防止多點同時登陸。

接下來我們需要從Sz.Network.ThreadPool 庫中取出一個線程

public static readonly long LoginThreadID = ThreadManager.GetInstance.GetThreadModel("登陸處理器");

用于控制登陸和登出

創建一個CloseTcpHandler 處理鏈接端口的處理程序需要繼承Sz.Network.ThreadPool 下面的TaskBase

 1  public class CloseTcpHandler : TaskBase 2     { 3  4         IOSession client; 5         SocketMessage message; 6  7         public CloseTcpHandler(IOSession client) 8             : base("Tcp登陸處理") 9         {10             this.client = client;11         }12 13 14         public override void TaskRun()15         {16                 17         }18     }
View Code

那么我們修改一下MessagePool 類

   public void ActiveSocket(IOSession client)        {            //client.SendMsg(new SocketMessage(1, System.Text.UTF8Encoding.Default.GetBytes("Holle Server!client")));        }        public void CloseSocket(IOSession client)        {            ThreadManager.GetInstance.AddTask(ServerManager.LoginThreadID, new CloseTcpHandler(client));        }

這樣斷開鏈接處理就交到了ServerManager.LoginThreadID 這個線程里面處理了

我們再來創建一下LoginTcpHandler 處理登陸程序 需要繼承Sz.Network.ThreadPool 下面的TaskBase

View Code

修改MessagePool 類 處理登陸消息

 1 public void ReadMessage(IOSession client, SocketMessage message) 2         { 3             switch (message.MsgID) 4             { 5                 case 1://登陸  6                 case 2: 7                     ThreadManager.GetInstance.AddTask(ServerManager.LoginThreadID, new LoginTcpHandler(client, message)); 8                     break; 9                 default:10                     Logger.Error("未綁定消息ID " + message.MsgID);11                     break;12             }13         }

這里是我自定義消息ID是1和2的一個是登陸一個是登出。

這樣就把登陸的事件也交給了ServerManager.LoginThreadID 這個線程里面處理了

LoginTcpHandler taskrun方法

 1  public override void TaskRun() 2         { 3             using (MemoryStream msReader = new MemoryStream(message.MsgBuffer)) 4             { 5                 using (System.IO.BinaryReader srReader = new BinaryReader(msReader, UTF8Encoding.Default)) 6                 { 7                     using (MemoryStream msWriter = new MemoryStream()) 8                     { 9                         using (System.IO.BinaryWriter srWriter = new BinaryWriter(msWriter, UTF8Encoding.Default))10                         {11                             switch (message.MsgID)12                             {13                                 case 1://登陸 14                                     string username = srReader.ReadString();15                                     if (!LoginManager.GetInstance.LoginNames.Contains(username))16                                     {17                                         LoginManager.GetInstance.LoginNames.Add(username);18                                         if (!LoginManager.GetInstance.Loginips.ContainsKey(client.ID))19                                         {20                                             LoginManager.GetInstance.LoginIPs[client.ID] = username;21                                             LoginManager.GetInstance.Sessions.Add(client);22                                         }23                                         srWriter.Write(true);24                                         srWriter.Write(username + " 登陸聊天室");25                                         Logger.Info(client.RemoteEndPoint + " " + username + " 登陸成功");26                                         SocketMessage sm = new SocketMessage(message.MsgID, msWriter.GetBuffer());27                                         ServerManager.GetInstance.Tell_All(sm);28                                     }29                                     else30                                     {31                                         srWriter.Write(false);32                                         srWriter.Write("登錄名稱重復,請換一個");33                                         Logger.Info(client.RemoteEndPoint + " " + username + " 登錄名稱重復!");34                                         SocketMessage sm
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁海县| 浦北县| 宁南县| 泰和县| 华坪县| 轮台县| 师宗县| 平南县| 绥中县| 呼玛县| 彰武县| 诏安县| 安泽县| 吉木乃县| 辽宁省| 宣化县| 长丰县| 巩义市| 大新县| 浦城县| 商都县| 尼勒克县| 延长县| 南涧| 湘西| 漾濞| 玉田县| 台东县| 中西区| 宝兴县| 德安县| 阳城县| 昌图县| 城固县| 库车县| 澳门| 洪湖市| 吉木萨尔县| 天全县| 古田县| 晋城|