OMG,到底在尋找什么..................
          (構(gòu)造一個完美的J2EE系統(tǒng)所需要的完整知識體系)
          posts - 198,  comments - 37,  trackbacks - 0
          原貼地址:http://blog.csdn.net/clearwater21cn/category/99145.aspx

          QuickServer開發(fā)指南(6)- 遠程管理支持

          我們的EchoServer可能需要修改幾個服務(wù)器配置參數(shù),如超時消息、最多驗證數(shù)、最大驗證時間。QuickServer支持這些功能而無須改變代碼。

          1.?使用QSAdminServer
          ??? 當我們需要一個管理服務(wù)器來控制我們的服務(wù)器時,我們不需要修改代碼甚至關(guān)閉正在運行的服務(wù)器。這項服務(wù)的實現(xiàn)類是:
          ??? org.quickserver.net.qsadmin.QSAdminServer
          ??? 要使用它的功能我們要調(diào)用QuickServer的startQSAdminServer()方法。QSAdminServer運行的默認端口是9876,我們可以使用下面兩個方法之一修改它:
          ??? setQSAdminServerPort(4124);
          ??? getQSAdminServer().getServer().setPort(4124);
          ??? 下面是能夠在EchoServer 的4124端口運行QSAdminServer 的代碼:

          01 package echoserver;

          02

          03 import org.quickserver.net.*;

          04 import org.quickserver.net.server.*;

          05

          06 import java.io.*;

          07

          08 public class EchoServer {

          09 public static void main(String s[]) {

          10

          11 String cmd = "echoserver.EchoCommandHandler";

          12 String auth = "echoserver.EchoServerQuickAuthenticator";

          13 String data = "echoserver.EchoServerPoolableData"; //Poolable

          14

          15 QuickServer myServer = new QuickServer(cmd);

          16 myServer.setAuthenticator(auth);

          17 myServer.setClientData(data);

          18

          19 myServer setPort(4123);

          20 myServer.setName("Echo Server v 1.0");

          21

          22 //config QSAdminServer

          23 myServer.setQSAdminServerPort(4124);

          24 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");

          25 try {

          26 myServer.startQSAdminServer();

          27 myServer.startServer();

          28 } catch(AppException e){

          29 System.out.println("Error in server : "+e);

          30 }

          31 }

          32 }

          33


          ??? 這樣,我們定義了我們的QSAdminServer運行在4124端口。但是它怎樣進行驗證呢?如果沒有一個外在的驗證器,QSAdminServer將使用org.quickserver.net.qsadmin.Authenticator做為它的驗證器。查閱API文檔我們可以發(fā)現(xiàn)它非常簡單,用戶名和密碼都被硬編碼為:
          ??? 用戶名 : Admin
          ??? 密碼 : QsAdm1n
          ??? 現(xiàn)在讓我們編譯新的程序并運行之,控制臺將會輸出信息以說明服務(wù)器運行于4124端口。

          ??? 在QuickServer安裝目錄下的bin目錄下運行QsAdminGUI.bat,QsAdmin的界面如下所示


          ??? 現(xiàn)在可以連接到管理服務(wù)器了。點擊右上角的"Login"按鈕,將會彈出一個登錄對話框如下圖,輸入IP地址和服務(wù)器運行端口:127.0.0.1、4124,因為我們使用默認的用戶名密碼,直接點擊"Login"登錄。
          ??? 登錄后界面將會顯示歡迎及登錄成功信息?,F(xiàn)在可以選擇發(fā)送命令的目標服務(wù)器(Target)及左邊一排命令按鈕所示的操作。

          ??? Target是基于發(fā)送命令的服務(wù)器,因為我們目前有兩個服務(wù)器EchoServer和EchoAdmin。
          ??? 界面右下邊有一個可以直接向服務(wù)器發(fā)送消息的文本框,命令可以參考QsAdmin command handler:
          ??? org.quickserver.net.qsadmin.CommandHandler API文檔
          ??? 若想要改變服務(wù)器的配置,可以點選"Get/Set"書簽,只要選擇"Target",點擊"Reload Properties For The Target"以重新加載目標服務(wù)器的配置。修改好參數(shù),然后點擊"Save"就可以了。部分參數(shù)的生效需要重啟服務(wù)器,不過這樣不會斷開與客戶端的連接。

          2.?添加自己的命令
          ??? 前面講過如果我們想改變一些服務(wù)器的屬性,我們無須修改已有的代碼或重啟服務(wù)器,我們可以添加自己的命令來管理服務(wù)器。
          ??? 讓我們用一個例子來演示這個功能。當用戶發(fā)送"What's interest"(利息是多少)時,我們將要顯示當前的利率。這個數(shù)字存貯在一個對象中,如果需要的話,無須重啟服務(wù)器就可以改變它。我們說它是可變的并且當服務(wù)器運行時我們需要改變它。
          ??? 我們來實現(xiàn)command handler以顯示利率。首先要改變EchoServer和command handler。下面是代碼:

          01 package echoserver;

          02

          03 import org.quickserver.net.*;

          04 import org.quickserver.net.server.*;

          05

          06 import java.io.*;

          07

          08 public class EchoServer {

          09 public static void main(String s[]) {

          10

          11 String cmd = "echoserver.EchoCommandHandler";

          12 String auth = "echoserver.EchoServerQuickAuthenticator";

          13 String data = "echoserver.EchoServerPoolableData"; //Poolable

          14

          15 QuickServer myServer = new QuickServer(cmd);

          16 myServer.setAuthenticator(auth);

          17 myServer.setClientData(data);

          18

          19 myServer.setPort(4123);

          20 myServer.setName("Echo Server v 1.0");

          21

          22 //store data needed to be changed by QSAdminServer

          23 Object[] store = new Object[]{"12.00"};

          24 myServer setStoreObjects(store);

          25

          26 //config QSAdminServer

          27 myServer.setQSAdminServerPort(4124);

          28 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");

          29 try {

          30 myServer.startQSAdminServer();

          31 myServer.startServer();

          32 } catch(AppException e){

          33 System.out.println("Error in server : "+e);

          34 }

          35 }

          36 }

          37



          01 // EchoCommandHandler.java

          02 package echoserver;

          03

          04 import java.net.*;

          05 import java.io.*;

          06 import org.quickserver.net.server.ClientCommandHandler;

          07 import org.quickserver.net.server.ClientHandler;

          08

          09 public class EchoCommandHandler implements ClientCommandHandler {

          10

          11 public void gotConnected(ClientHandler handler)

          12 throws SocketTimeoutException, IOException {

          13 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

          14 handler.sendClientMsg("| Welcome to EchoServer v 1.0 |");

          15 handler.sendClientMsg("| Note: Password = Username |");

          16 handler.sendClientMsg("| Send 'Quit' to exit |");

          17 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

          18 }

          19 public void lostConnection(ClientHandler handler)

          20 throws IOException {

          21 handler.sendSystemMsg("Connection lost : " +

          22 handler.getSocket().getInetAddress());

          23 }

          24 public void closingConnection(ClientHandler handler)

          25 throws IOException {

          26 handler.sendSystemMsg("Closing connection : " +

          27 handler.getSocket().getInetAddress());

          28 }

          29

          30 public void handleCommand(ClientHandler handler, String command)

          31 throws SocketTimeoutException, IOException {

          32 if(command.equals("Quit")) {

          33 handler.sendClientMsg("Bye ;-)");

          34 handler.closeConnection();

          35 return;

          36 }

          37 if(command.equals("What's interest?")) {

          38 handler.sendClientMsg("Interest is : "+

          39 (String)handler.getServer().getStoreObjects()[0]+

          40 "%");

          41 } else if(command.equalsIgnoreCase("hello")) {

          42 EchoServerData data = (EchoServerData) handler.getClientData();

          43 data.setHelloCount(data.getHelloCount()+1);

          44 if(data.getHelloCount()==1) {

          45 handler.sendClientMsg("Hello "+data.getUsername());

          46 } else {

          47 handler.sendClientMsg("You told Hello "+data.getHelloCount()+

          48 " times. ");

          49 }

          50 } else {

          51 handler.sendClientMsg("Echo : "+command);

          52 }

          53 }

          54 }


          ??? 接下來為QSAdminServer 添加Command插件

          01 package echoserver;

          02

          03

          04 import java.io.*;

          05 import java.net.SocketTimeoutException;

          06 import org.quickserver.net.server.*;

          07 import org.quickserver.net.qsadmin.*;

          08

          09 public class QSAdminCommandPlugin implements CommandPlugin {

          10 /**

          11 * Echoserver commands

          12 * ----------------------------------

          13 * set interest value

          14 * get interest

          15 */

          16 public boolean handleCommand(ClientHandler handler, String command)

          17 throws SocketTimeoutException, IOException {

          18

          19 QuickServer echoserver = (QuickServer)

          20 handler.getServer().getStoreObjects()[0];

          21 Object obj[] = echoserver.getStoreObjects();

          22

          23 if(command.toLowerCase().startsWith("set interest ")) {

          24 String temp = "";

          25 temp = command.substring("set interest ".length());

          26 obj[0] = temp;

          27 echoserver.setStoreObjects(obj);

          28 handler.sendClientMsg("+OK interest changed");

          29 return true;

          30 } else if(command.toLowerCase().equals("get interest")) {

          31 handler.sendClientMsg("+OK " + (String)obj[0]);

          32 return true;

          33 }

          34 //ask QSAdminServer to process the command

          35 return false;

          36 }

          37 }

          ??? 在上面的代碼中,我們使用下面的代碼調(diào)用了EchoServer的QSAdminServer中的存貯對象。(參考QuickServer API 文檔中的QSAdminServer和CommandPlugin部分)。
          ??? QuickServer echoserver = (QuickServer)handler.getServer().getStoreObjects()[0];
          ??? 如果進程獲得了一個命令,返回true,否則返回false,并指明QSAdminServer的默認命令處理器將被用來處理命令。同樣的技術(shù)將被使用于覆寫QSAdminServer命令處理器的默認命令。

          ??? 讓我們告訴QuickServer這個類是QSAdminServer的Command插件。修改后的EchoServer.java代碼如下:

          01 package echoserver;

          02

          03 import org.quickserver.net.*;

          04 import org.quickserver.net.server.*;

          05

          06 import java.io.*;

          07

          08 public class EchoServer {

          09 public static void main(String s[]) {

          10

          11 String cmd = "echoserver.EchoCommandHandler";

          12 String auth = "echoserver.EchoServerQuickAuthenticator";

          13 String data = "echoserver.EchoServerPoolableData"; //Poolable

          14

          15 QuickServer myServer = new QuickServer(cmd);

          16 myServer.setAuthenticator(auth);

          17 myServer.setClientData(data);

          18

          19 myServer.setPort(4123);

          20 myServer.setName("Echo Server v 1.0");

          21

          22 //store data needed to be changed by QSAdminServer

          23 Object[] store = new Object[]{"12.00"};

          24 myServer.setStoreObjects(store);

          25

          26 //config QSAdminServer

          27 myServer.setQSAdminServerPort(4124);

          28 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");

          29 try {

          30 //add command plugin

          31 myServer.getQSAdminServer().setCommandPlugin(

          32 "echoserver.QSAdminCommandPlugin");

          33 myServer startQSAdminServer();

          34 myServer.startServer();

          35 } catch(AppException e){

          36 System.out.println("Error in server : "+e);

          37 } catch(Exception e){

          38 System.out.println("Error : "+e);

          39 }

          40 }

          41 }


          ??? 編譯代碼,并運行?,F(xiàn)在打開客戶端如SocketTest,發(fā)送命令"What's interest?",將顯示"Interest is : 12.00%"。
          ??? 運行QSAdminGUI,在發(fā)送消息框中鍵入以下命令,發(fā)送:
          ??? get interest
          ??? 系統(tǒng)輸出"+OK 12.00"
          ??? 現(xiàn)在把這個參數(shù)修改一下,發(fā)送下面的命令
          ??? ?set interest 15.00
          ??? 系統(tǒng)輸出"+OK interest changed"
          ??? 再次在客戶端發(fā)送命令"What's interest?",客戶端顯示"Interest is : 15.00%"。


          QuickServer開發(fā)指南(7)- 使用和定制日志

          對任何一個項目來說,日志都是一個重要的工具。日志幫助我們?nèi)ダ斫馕覀兊捻椖績?nèi)部發(fā)生了什么,它也會提供審核和調(diào)試信息。想要知道更多有關(guān)日志的資料可查閱Sun公司的網(wǎng)站
          ??? http://java.sun.com/j2se/1.4.0/docs/guide/util/logging/overview.html
          ??? QuickServer目前只支持Java Logging API (java.util.logging)。1.4版的Java已加入logging。如果你還在使用舊的版本,你可以安裝Lumberjack庫提供的可選的實現(xiàn)(http://javalogging.sourceforge.net/)。
          ??? 讓我們給我們的EchoServer做一個日志器。QuickServer默認已可以使用日志器,但是除了ConsoleHandler和設(shè)置INFO的級別之外它什么也沒有處理。因而無論何時我們在EchoServer關(guān)閉和客戶端的連接,我們都會在控制臺看見一些相似的信息
          ??????? Feb 16, 2000 10:11:25 PM ClientHandler sendSystemMsg
          ??????? INFO: Closing connection : /127.0.0.1
          ??? 上面的信息指明IP為127.0.0.1的客戶端關(guān)閉了連接。這條消息的顯示使用了ClientHalder類的sendSystemMsg()方法.
          ??? 讓我們看看我們怎樣在我們的項目中控制日志。使用java logging必須先在類中導(dǎo)入java.util.logging包。
          ??? 從上面的日志,我們發(fā)現(xiàn)某些客戶端關(guān)閉了連接或掉線,但是它是怎樣顯示的,我們并沒有寫任何有關(guān)日志的命令。它會顯示是因為QuickServer使用了內(nèi)部的日志器ClientHandler類的sendSystemMsg()方法。
          ??? 查看QuickServer文檔可以找到sendSystemMsg(),如果沒有指定級別,它默認使用INFO。你可以在ClientCommandHandler或Authenticator或任何類中使用sendSystemMsg()來記錄一個事件。

          1.?簡單的日志
          ?? 現(xiàn)在我們來記錄每一個連接EchoServer的客戶端IP地址。編輯EchoCommandHandler.java文件。在gotConnected(ClientHandler handler)后添加
          ??? handler.sendSystemMsg("New Client : " +
          ????????????????????????? handler.getSocket().getInetAddress().getHostAddress(),
          ????????????????????????? Level.INFO);
          ?? 還要導(dǎo)入包import java.util.logging.*;
          ?? 編譯并運行,連接到EchoServer,你將看到當客戶端連接時控制臺會顯示你的地址。
          ?? 讓QuickServer將日志記錄到文件中(XML格式)。下面是修改的文件:

          01 package echoserver;

          02

          03 import org.quickserver.net.*;

          04 import org.quickserver.net.server.*;

          05

          06 import java.io.*;

          07 import java.util.logging.*;

          08

          09 public class EchoServer {

          10 public static void main(String s[]) {

          11

          12 String cmd = "echoserver.EchoCommandHandler";

          13 String auth = "echoserver.EchoServerQuickAuthenticator";

          14 String data = "echoserver.EchoServerPoolableData"; //Poolable

          15

          16 QuickServer myServer = new QuickServer();

          17

          18 //setup logger to log to file

          19 Logger logger = null;

          20 FileHandler xmlLog = null;

          21 File log = new File("./log/");

          22 if(!log.canRead())

          23 log.mkdir();

          24 try {

          25 logger = Logger.getLogger(""); //get root logger

          26 logger.setLevel(Level.INFO);

          27 xmlLog = new FileHandler("log/EchoServer.xml");

          28 logger.addHandler(xmlLog);

          29 } catch(IOException e){

          30 System.err.println("Could not create xmlLog FileHandler : "+e);

          31 }

          32 //set logging level to fine

          33 myServer setConsoleLoggingLevel(Level INFO);

          34

          35

          36 myServer.setClientCommandHandler(cmd);

          37 myServer.setAuthenticator(auth);

          38 myServer.setClientData(data);

          39

          40 myServer.setPort(4123);

          41 myServer.setName("Echo Server v 1.0");

          42

          43 //store data needed to be changed by QSAdminServer

          44 Object[] store = new Object[]{"12.00"};

          45 myServer.setStoreObjects(store);

          46

          47 //config QSAdminServer

          48 myServer.setQSAdminServerPort(4124);

          49 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");

          50 try {

          51 //add command plugin

          52 myServer.getQSAdminServer().setCommandPlugin(

          53 "echoserver.QSAdminCommandPlugin");

          54 myServer.startQSAdminServer();

          55 myServer.startServer();

          56 } catch(AppException e){

          57 System.out.println("Error in server : "+e);

          58 } catch(Exception e){

          59 System.out.println("Error : "+e);

          60 }

          61 }

          62 }


          ??? 在上面的代碼中,我們首先檢查是否存在一個日志文件夾(21、22行),如果沒有先創(chuàng)建它。
          ??? 在25行,我們嘗試獲得一個日志器,28行,添加一個新的FileHandler,這里我們沒有指定格式因為默認的格式就是XML的。
          ??? 在33行,我們設(shè)置日志的控制級別為INFO。
          ??? 接下來修改EchoCommandHandler.java

          01 // EchoCommandHandler.java

          02 package echoserver;

          03

          04 import java.net.*;

          05 import java.io.*;

          06 import org.quickserver.net.server.ClientCommandHandler;

          07 import org.quickserver.net.server.ClientHandler;

          08 import java.util.logging.*;

          09

          10 public class EchoCommandHandler implements ClientCommandHandler {

          11

          12 public void gotConnected(ClientHandler handler)

          13 throws SocketTimeoutException, IOException {

          14 handler.sendSystemMsg("New Client : "+

          15 handler.getSocket().getInetAddress().getHostAddress(),

          16 Level.INFO);

          17 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

          18 handler.sendClientMsg("| Welcome to EchoServer v 1.0 |");

          19 handler.sendClientMsg("| Note: Password = Username |");

          20 handler.sendClientMsg("| Send 'Quit' to exit |");

          21 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

          22 }

          23 public void lostConnection(ClientHandler handler)

          24 throws IOException {

          25 handler.sendSystemMsg("Connection lost : " +

          26 handler.getSocket().getInetAddress());

          27 }

          28 public void closingConnection(ClientHandler handler)

          29 throws IOException {

          30 handler.sendSystemMsg("Closing connection : " +

          31 handler.getSocket().getInetAddress());

          32 }

          33

          34 public void handleCommand(ClientHandler handler, String command)

          35 throws SocketTimeoutException, IOException {

          36 if(command.equals("Quit")) {

          37 handler.sendClientMsg("Bye ;-)");

          38 handler.closeConnection();

          39 return;

          40 }

          41 if(command.equals("What's interest?")) {

          42 handler.sendClientMsg("Interest is : "+

          43 (String)handler.getServer().getStoreObjects()[0]+

          44 "%");

          45 } else if(command.equalsIgnoreCase("hello")) {

          46 EchoServerData data = (EchoServerData) handler.getClientData();

          47 data.setHelloCount(data.getHelloCount()+1);

          48 if(data.getHelloCount()==1) {

          49 handler.sendClientMsg("Hello "+data.getUsername());

          50 } else {

          51 handler.sendClientMsg("You told Hello "+data.getHelloCount()+

          52 " times. ");

          53 }

          54 } else {

          55 handler.sendClientMsg("Echo : "+command);

          56 }

          57 }

          58 }


          ??? 編譯并運行程序,現(xiàn)在嘗試連接,你將看到它會同時在控制臺和xml文件記錄你的IP地址。
          ??? 讓我們使用QSAdminGUI設(shè)置日志級別為FINEST,觀察日志內(nèi)容的變化。日志記錄增加了。另外一個改變?nèi)罩炯墑e的方法是修改代碼,可以使用logger.setLevel()或者QuickServer的方法setLoggingLevel()來設(shè)置所有句柄的日志級別。

          2.?日志的高級應(yīng)用
          ??? 當我們設(shè)置日志級別為FINEST時,會記錄很多信息。一個可能的需要是分離QuickServer和應(yīng)用的日志。下面的代碼允許你這么做。

          01 package echoserver;

          02

          03 import org.quickserver.net.*;

          04 import org.quickserver.net.server.*;

          05

          06 import java.io.*;

          07 import java.util.logging.*;

          08

          09 public class EchoServer {

          10 public static void main(String s[]) {

          11

          12 String cmd = "echoserver.EchoCommandHandler";

          13 String auth = "echoserver.EchoServerQuickAuthenticator";

          14 String data = "echoserver.EchoServerPoolableData"; //Poolable

          15

          16 QuickServer myServer = new QuickServer();

          17

          18 //setup logger to log to file

          19 Logger logger = null;

          20 FileHandler xmlLog = null;

          21 FileHandler txtLog = null;

          22 File log = new File("./log/");

          23 if(!log.canRead())

          24 log.mkdir();

          25 try {

          26 logger = Logger.getLogger("org.quickserver.net"); //get QS logger

          27 logger.setLevel(Level.FINEST);

          28 xmlLog = new FileHandler("log/EchoServer.xml");

          29 logger.addHandler(xmlLog);

          30

          31 logger = Logger.getLogger("echoserver"); //get App logger

          32 logger.setLevel(Level.FINEST);

          33 txtLog = new FileHandler("log/EchoServer.txt");

          34 txtLog.setFormatter(new SimpleFormatter());

          35 logger.addHandler(txtLog);

          36 myServer.setAppLogger(logger); //img : Sets logger to be used for app.

          37 } catch(IOException e){

          38 System.err.println("Could not create xmlLog FileHandler : "+e);

          39 }

          40 //set logging level to fine

          41 myServer.setConsoleLoggingLevel(Level.INFO);

          42

          43

          44 myServer.setClientCommandHandler(cmd);

          45 myServer.setAuthenticator(auth);

          46 myServer.setClientData(data);

          47

          48 myServer.setPort(4123);

          49 myServer.setName("Echo Server v 1.0");

          50

          51 //store data needed to be changed by QSAdminServer

          52 Object[] store = new Object[]{"12.00"};

          53 myServer.setStoreObjects(store);

          54

          55 //config QSAdminServer

          56 myServer.setQSAdminServerPort(4124);

          57 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");

          58 try {

          59 //add command plugin

          60 myServer.getQSAdminServer().setCommandPlugin(

          61 "echoserver.QSAdminCommandPlugin");

          62 myServer.startQSAdminServer();

          63 myServer.startServer();

          64 } catch(AppException e){

          65 System.out.println("Error in server : "+e);

          66 } catch(Exception e){

          67 System.out.println("Error : "+e);

          68 }

          69 }

          70 }


          ??? 代碼中的注釋說明的很清楚了。編譯并運行,連接后你將看見QuickServer內(nèi)部的日志記錄到了xml文件,應(yīng)用級別的日志記錄到了我們想要的txt文件。

          注意:
          ??? 要盡量減少控制臺中的日志數(shù)量,使用文件記錄詳細的日志,并降低日志的級別。這樣可以改善應(yīng)用的性能。避免使用System.out.println(),用logging代替。ClientHandler中的sendSystemMsg()方法在記錄日志方面很有用。


          QuickServer開發(fā)指南(8)- XML配置

          在前面的章節(jié)里我們擴展了EchoServer。我們已經(jīng)在類中配置了QuickServer,在某些情況下這是可接受的。但是很多應(yīng)用更希望用戶能夠在應(yīng)用啟動后動態(tài)配置應(yīng)用。給QuickServer添加這方面功能,你可以告訴服務(wù)器讀取XML文件并實例化它。
          ??? 要配置QuickServer首先要寫配置文件,然后告訴QuickServer加載這個配置。下面是一個非常簡單的配置文件
          ??? <quickserver>
          ??????? <name>EchoServer v 1.0</name>
          ??????? <client-command-handler>
          ??????????? echoserver.EchoCommandHandler
          ??????? </client-command-handler>
          ??? </quickserver>
          ??? 現(xiàn)在有兩種方式啟動服務(wù)器
          • 使用QuickServer啟動參數(shù)--load
            在這里你要做的是在啟動QuickServer時使用"-load"指定xml配置文件的路徑。例如
            java -jar QuickServer.jar -load myxmlconfig.xml

            java org.quickserver.net.server.QuickServer -load myxmlconfig.xml

            quickserver.bat -load myxmlconfig.xml
          • 使用QuickServer的initService()方法
            有時你可能需要在啟動你的應(yīng)用時使用自己的jar文件或類文件,或者你可能想要在啟動前添加一些代碼,那么這個選擇是最合適的。下面的代碼通過xml配置文件初始化了QuickServer。
            QuickServer myServer = new QuickServer();
            //pick the xml file form config folder
            String confFile = "conf" + File.separator + "MyServer.xml";
            Object config[] = new Object[] {confFile};
            if(myServer.initService(config) != true) {
            System.err.println("Could't init server !!");
            }

          現(xiàn)在我們來給我們的EchoServer寫配置文件。下面是XML文件

          01 <quickserver>

          02 <name>EchoServer v 1.0</name>

          03 <port>4123</port>

          04 <bind-address>127.0.0.1</bind-address>

          05

          06 <client-command-handler>

          07 echoserver.EchoCommandHandler

          08 </client-command-handler>

          09 <authenticator>

          10 echoserver.EchoServerQuickAuthenticator

          11 </authenticator>

          12 <client-data>

          13 echoserver.EchoServerPoolableData

          14 </client-data>

          15

          16 <console-logging-level>INFO</console-logging-level>

          17

          18 <!-- some extra config. added just to show -->

          19 <timeout>4</timeout>

          20 <timeout-msg>-ERR Timeout</timeout-msg>

          21 <max-auth-try>5</max-auth-try>

          22 <max-auth-try-msg>-ERR Max Auth Try Reached</max-auth-try-msg>

          23 <max-connection>-1</max-connection>

          24 <max-connection-msg>

          25 Server Busy\nMax Connection Reached

          26 </max-connection-msg>

          27 <object-pool>

          28 <max-active>-1</max-active>

          29 <max-idle>15</max-idle>

          30 </object-pool>

          31 <!-- some extra config. added just to show -->

          32

          33 <qsadmin-server>

          34 <name>EchoAdmin v 1.0</name>

          35 <port>4124</port>

          36 <bind-address>127.0.0.1</bind-address>

          37 <command-plugin>

          38 echoserver.QSAdminCommandPlugin

          39 </command-plugin>

          40 </qsadmin-server>

          41
          42 </quickserver>


          下面是修改過的EchoServer.java文件,它現(xiàn)在可以從xml文件加載配置

          01 package echoserver;

          02

          03 import org.quickserver.net.*;

          04 import org.quickserver.net.server.*;

          05

          06 import java.io.*;

          07 import java.util.logging.*;

          08

          09 public class EchoServer {

          10 public static void main(String s[]) {

          11

          12 QuickServer myServer = new QuickServer();

          13

          14 //setup logger to log to file

          15 Logger logger = null;

          16 FileHandler xmlLog = null;

          17 FileHandler txtLog = null;

          18 File log = new File("./log/");

          19 if(!log.canRead())

          20 log.mkdir();

          21 try {

          22 logger = Logger.getLogger("org.quickserver.net"); //get qs logger

          23 logger.setLevel(Level.FINEST);

          24 xmlLog = new FileHandler("log/EchoServer.xml");

          25 logger.addHandler(xmlLog);

          26

          27 logger = Logger.getLogger("echoserver"); //get app logger

          28 logger.setLevel(Level.FINEST);

          29 txtLog = new FileHandler("log/EchoServer.txt");

          30 txtLog.setFormatter(new SimpleFormatter());

          31 logger.addHandler(txtLog);

          32 //img : Sets logger to be used for app.

          33 myServer.setAppLogger(logger);

          34 } catch(IOException e){

          35 System.err.println("Could not create xmlLog FileHandler : "+e);

          36 }

          37

          38 //store data needed to be changed by QSAdminServer

          39 Object[] store = new Object[]{"12.00"};

          40 myServer.setStoreObjects(store);

          41

          42 //load QuickServer from xml

          43 String confFile = "config"+File.separator+"EchoServer.xml";

          44 Object config[] = new Object[] {confFile};

          45 if(myServer.initService(config) == true) {

          46 try {

          47 myServer.startQSAdminServer();

          48 myServer.startServer();

          49 } catch(AppException e){

          50 System.out.println("Error in server : "+e);

          51 } catch(Exception e){

          52 System.out.println("Error : "+e);

          53 }

          54 }

          55 }

          56 }

          57

          ??? 想要知道更多的XML配置請參考QuickServer Java文檔(主頁有一個xml樣本)以及QuickServer提供的例子。


          QuickServer開發(fā)指南(9)- 數(shù)據(jù)模式和數(shù)據(jù)類型

          直到現(xiàn)在我們的通信還是僅僅在使用以<CR><LF>結(jié)尾的字符串。當然,在Internet標準協(xié)議里它是最常用的。但有時我們可能需要接收字節(jié)流或Java對象。
          ??? 下面是數(shù)據(jù)模式和數(shù)據(jù)類型,使用它你可以告訴ClientHandler使用哪一種通信模式。
          ??? 數(shù)據(jù)模式用于定義QuickServer和客戶Socket之間的數(shù)據(jù)交換格式。下面是目前支持的三種模式:
          • DataMode.STRING - 這是默認的交換模式,在這種模式下你可以接收字符串數(shù)據(jù)(以<CR><LF>結(jié)尾)
          • ?DataMode.OBJECT - 在這種模式里你可以接收可序列化的Java對象。這種模式僅僅使用在客戶端可以寫java的情況下。
          • ?DataMode.BYTE - 在這種模式下你可以接收客戶端發(fā)送的所有字節(jié),包括<CR>或<LF>或任何其它控制字符。這種模式在處理基于客戶機或無標準協(xié)議如xml或你自己定義的協(xié)議的硬件時非常有用。
            數(shù)據(jù)類型用戶定義QuickServer和客戶Socket之間的數(shù)據(jù)交換類型。目前有兩種格式:
          • DataType.IN - 指定數(shù)據(jù)為輸入QuickServer的數(shù)據(jù)。
          • DataType.OUT - 指定數(shù)據(jù)為從QuickServer輸出的數(shù)據(jù)。

          ??? 任何數(shù)據(jù)類型的數(shù)據(jù)模式都可以使用ClientHandler的setDataMode()方法設(shè)置,格式如下
          ??? setDataMode(DataMode dataMode, DataType dataType)
          注意:
          ??? 當模式為DataMode.OBJECT類型為DataType.IN,調(diào)用將會阻塞,直到客戶端的ObjectOutputStream被寫和頭被刷新。


          posted on 2006-12-04 19:49 OMG 閱讀(1909) 評論(0)  編輯  收藏 所屬分類: Soket

          <2006年12月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          IT風云人物

          文檔

          朋友

          相冊

          經(jīng)典網(wǎng)站

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 梓潼县| 盐池县| 吉首市| 文山县| 银川市| 苏州市| 辉南县| 西峡县| 四会市| 兴宁市| 庆元县| 武清区| 潮州市| 漳浦县| 农安县| 榆树市| 金堂县| 博客| 名山县| 石景山区| 依安县| 肇庆市| 游戏| 遂昌县| 增城市| 科技| 嘉荫县| 厦门市| 新龙县| 措美县| 东光县| 广宗县| 汽车| 民丰县| 共和县| 邛崃市| 赣州市| 兴化市| 赞皇县| 湛江市| 柏乡县|