作者:江南白衣?

??? 雖然現在已是Web Server, Web Service的天下,但偶然還是會因為性能苛刻,或者需要自定義協議的原因,很無辜的要自己做一個Multi-Thread,Multi-Client的Tcp Server。

???? 第一時間想起了那兩卷UNP(《Unix Network Programing》),好在現在除了Ice的Java版,Netty2作者的后續之作Apache MINA,CrmkyCindy之外,還有個超簡單的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配置地獄。