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