作者:
江南白衣?
??? 雖然現在已是Web Server, Web Service的天下,但偶然還是會因為性能苛刻,或者需要自定義協議的原因,很無辜的要自己做一個Multi-Thread,Multi-Client的Tcp Server。
???? 第一時間想起了那兩卷UNP(《Unix Network Programing》),好在現在除了Ice的Java版,Netty2作者的后續之作Apache MINA,Crmky的Cindy之外,還有個超簡單的QuickServer,讓你專心編寫自己的業務代碼,不用編寫一行Tcp代碼。
???? 本來還想花點時間在幾種框架之間好好選型的,但就在一個無聊會議的間隙里,嘗試著用QuickServer編寫一點代碼,結果才十幾行代碼就把任務完成了,還選什么型呢?因此,也把QuickServer作為這個Pragmatic系列的開端。
????? 一開始吸引我的是QuickServer的Quick?Start,編寫hanlder類和xml配置文件后,用java? -jar QuickServer.jar -load EchoServer.xml??啟動就可以了。
????
XML配置文件:
<quickserver>
????<name>EchoServer?v?1.2</name>
????<port>4123</port>
????<bind-address>0.0.0.0</bind-address>
????<!--?business?logic?classes?-->
????<client-command-handler>
????????org.springside.EchoCommandHandler
????</client-command-handler>
</quickserver>
唯一需要的Hanlder類:
public?class?EchoCommandHandler?implements?ClientCommandHandler?{
????public?void?handleCommand(ClientHandler?handler,?String?command)?throws?SocketTimeoutException,?IOException?{
????????if(command.toLowerCase().equals("quit"))?{
????????????handler.sendClientMsg("Bye?;-)");
????????????handler.closeConnection();
????????}?else?{
????????????handler.sendClientMsg("Echo?:?"+command);
????????}
????}
?}
??? 代碼里只有handleCommand(ClientHandler?handler,?String?command)這個回調函數是必須的方法,參數String command 是從客戶端傳來的字串,你可以定義自己的指令協議,也有byte[]和Java Object的形式。參數clientHandler 可以對client作任何事情,比如sendClientMsg()發送String形式的回應,當然還可以發送byte[]和Java Object。
??? handleCommand() 將框架的理念發揮到極致,你完全不需要關心Tcp編程的底層,不需要API式的線性編程,只要實現并配置回調函數,用框架傳來的command與handler干活就可以了,框架會完成前后一切的控制工作。
??? 但這個例子太沒營養了?在我的任務里,有Query:keyword, Detail:i 和 Bye三種指令,靜態初始化Spring的ClasspathXmlApplicationContext,通過getBean("searchService")拿到搜索服務對象進行搜索,最后學WebService,用jdom簡單的將搜索結果序列化成xml傳給Delphi客戶端解讀。
??? 另一個接口是EventHandler,可以對Client的gotConnected,closingConnection 等事件響應。
????最后QuickServer提供了ChatServer、FTPServer等example;安全方面支持驗證模式;性能方面Charlse說單機上兩萬人沒問題....
??? 就這么多了,畢竟一個短會間隙就完成的東西,能有多復雜呢?Pragmatic就是這樣一個系列,介紹一些輕便的框架,大幅簡化大家的編程,專心編寫自己的業務代碼,不需要知道太多的底層細節,也沒有xml配置地獄。