高级性能服务器编程模型【IOCP完成端口】开发实现【二】
?
因為需要參考各種資料,所以還是需要一些時間才能夠做好的。
?
而且在開發中,還會面對一些不得不仔細去解決的問題。
?
我打算盡量從Win32API的基礎上面進行開發,能夠不使用Delphi封裝的類就不用,任何類都是無法避免多余的開銷,而我們往往只使用一兩個功能就付出那么大的代價,是否值得????
?
當然,別談跨平臺了,在中國,還是老老實實在Windows系統上面搞開發吧,而且服務器編程跟客戶端沒有直接的關系,客戶端,你仍然可以采用任何語言進行開發,或者只使用JSocket的客戶端控件就行。當然,如果時間允許,我們也可以自己封裝一個,其實都差不多的,沒有見得好到那里去。
?
客戶端跟服務端不同,不需要關注并發連接的問題,也不用太在乎內存碎片的問題,反正玩家幾個小時之后就會關機。常規情況下,那種病態的不用多說。
?
首先,我們不需要理會其它的邏輯處理等等事情,首務之急是構建我們的服務器內核。
?
要記住的是,我們采用的是非阻塞式的連接方式。
?
這些阻塞的意思是比如我給你打電話,我對你說:“嗨,回答我好嗎??”這個時候,我在給你發送信息,接著我就站著等住你的回答,如果你一直都沒有回答,那么好吧,我只能夠傻站著等你的回話。直到你回答了為止,我才能夠自由地活動。這種情況是不是很傻???
?
Delphi的控件面板也有IOCP完成端口的控件,只是它是阻塞式的。為了那個跨平臺,呵呵。
?
非阻塞式的剛剛相反,我給你發信息,不管你回不回答,同樣不影響我做其它事情。如果是投遞函數,投遞完畢后,立馬返回。
?
?
?
?
好,我們去做一個我們自己能夠控制的服務器控件。
為什么說是我們能夠控制的呢,這個是我個人最喜歡做的事情,但是很累。
只有我們親手去制作并且按照自己的想法去做的東西,我們才會清楚它的邏輯結構,并且在任何時候,出現任何問題,我們馬上能夠了解到那個地方出了問題,并且能夠隨時用最短的時間去修復它。
如果效率不理想,我們能夠隨時按照自己的理解來優化它。
這里我使用了隨時這個詞,當你面對著很多很多單元文件和很長很長的代碼的時候,如果不是你自己親手做的,誰能夠保證,你能夠如此爽快地隨時啊??
不管我們做什么,都希望使用最短的時間做出最理想的東西來,對吧。
這個最理想是相對的,如果你有編程經驗,應該不會對此有任何問題吧。
隨著你編程水平的提高,很多以往的東西都會變得——弱智,但是我告訴你,這些不是弱智,相反,你現在所擁有的一切都是構建在這些弱智的曾經行為上面的。
有的人,認為:現在已經有很多庫了,為什么我們還要繼續制造輪子,而且不一定造得更好。
我的認為是:我們造的是自己的輪子,它比任何一切都實在和性能更高。
什么是最高性能和最高效率,我敢說,很多人都想不明白這個問題。
實際上,還是老話,只有你自己能夠控制的東西才是最有效率的。
底層的東西,如果你認為這些才是最高效的,那么就得看看你對0和1的理解能力,看看你對CPU架構和微軟的各種操作系統的最底層級別的了解了,如果還不夠,你得對IDE編譯器底層架構最深入的了解了,從硬件編碼到系統的軟編碼,估計你要忙活一輩子,呵呵。
很多東西都是相對的,不要太難為自己。——也許是我自己在自我安慰吧,哈哈~就當是吧,我不介意就行。
原因很多,只要自己認為是這樣就好。
也許大家都在認為我在廢話多多,呵呵,是的,這個是我的“毛病”,大家將就吧。
?
OK,開始了——
首先,我們通過IDE上面的菜單項目——選擇,還是看我的視頻錄制,本來我打算做個視頻,然后在視頻里面,咱們一步一步地構建這個控件。
但是,我想了下,優酷打開視頻的時候,會播放大量的廣告。
可是我們辛苦的作品,卻免費地成了人家賺錢的通道,我不喜歡這樣。
我的東西可以免費的同時,不能夠增加任何垃圾的廣告進里面。
要么,廣告費,咱們分成,呵呵,想得天真,對吧。
?
那么我們做一些視頻轉換,做成GiF圖片文件,對于網頁來說,文件太大了,會有些少影響網頁的打開。
?
其實不是所有人都做過控件,那么我們采用很簡單的做法,不需要做得太復雜。
一個包就行,當然后面,我會提供一個圖標,控件嘛,總得有自己的圖標的對吧。
為什么搞成控件,很多原因,方便構建程序的時候增加IDE操作的交互吧。等等等。。。
如果是老鳥,請無視哈,呵呵。因為我的習慣就是這樣,簡單直接。
至于控件注冊部分,習慣上,我會放到另一個單元文件里面。
那么后面的圖標文件等操作將在以后的Gif文件里面演示。
需要在父類里面聲明幾個事件類型,方便我們在測試的時候或者在使用的時候調用。
先聲明一個同窗體界面交互的信息提示事件。
TServerInfoEvent = procedure (Sender: TObject; nMsg:String) of object;
這個事件主要是把控件運行的情況,反映出來,方便我們觀察代碼執行的情況。
然后我們需要在基類的私有區域聲明一個私有的事件成員字段。
strict private{信息反饋事件}FOnMsgInfoEvent: TServerInfoEvent;要注意——Strict這個修飾符,如果是從D7時期轉過來的同志,要注意采用了這個修飾符,那么在同一個單元里面,是不能夠調用這個區域的字段成員的。不像以前那樣了。
跟著在公有區域,聲明一個如下的屬性:
publicproperty OnMsgInfoEvent: TServerInfoEvent read FOnMsgInfoEvent write FOnMsgInfoEvent;那么在以后我們把控件安裝到IDE里面的時候,就會從屬性編輯器的事件界面那里看到這個事件了。
(大家也許認為應該添加在published區域,實際是需要這樣做的,但是我們將在子類里面公開這些需要公開的部分。
是的,我打算采用兩個類來操作。不用擔心,兩個類,不會很麻煩的。
控件注冊的類,其實要改為子類,但是現在大家姑且保留那些注冊內容,還沒有到這部分的操作。)
怎么使用它,跟你使用那些啥鼠標事件等等是一樣的,不同的是,你應該查看——nMsg這個字符串變量反饋回來的字符信息,你可以打印到Memo控件里面顯示出來。或者,你可以增加事件聲明的字段,比如,增加一個枚舉類型的變量,如果反饋回來的是某個值,跟著做相應的操作等等。
還是老話:按照你自己的想法去做。
以上,還需要一個事件調用函數。如下:
procedure MsgInfoEvent(Const nMsg:String;Const ErrorCode: Integer = -1);這個調用函數帶兩個參數,那么后面的這個參數也是對應于事件聲明的。我增加了報錯檢測碼,你們可以自己根據需要自己添加。如果你們想隨時改變這個檢測碼,然后使代碼發生改變,可以像JScoket控件那樣做,采用一個Var 的變量來操作。
?
TServerInfoEvent = procedure (Sender: TObject; nMsg:String; ErrorCode: Integer = -1) of object;或者:——
TServerInfoEvent = procedure (Sender: TObject; nMsg:String; Var ErrorCode: Integer) of object;?
當然后面,我們還需要添加其它的事件。一步一步來。
那么事件調用函數是如何執行的,看下面:
procedure TComponentIocpSock.MsgInfoEvent(const nMsg: String;const ErrorCode: Integer); beginFOnMsgInfoEvent(Self,nMsg,ErrorCode); end;記住ErrorCode這個參數早就被處理成默認初始化,所以在調用MsgInfoEvent函數的時候,你可以輸入參數,也可以忽略它。
轉載于:https://www.cnblogs.com/GameDelphi/archive/2012/08/27/2658833.html
總結
以上是生活随笔為你收集整理的高级性能服务器编程模型【IOCP完成端口】开发实现【二】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WCF RIA Service实体类中发
- 下一篇: 怎么强制限制div宽度