<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

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

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

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

    1.?使用QSAdminServer
    ??? 當(dāng)我們需要一個管理服務(wù)器來控制我們的服務(wù)器時,我們不需要修改代碼甚至關(guān)閉正在運行的服務(wù)器。這項服務(wù)的實現(xiàn)類是:
    ??? org.quickserver.net.qsadmin.QSAdminServer
    ??? 要使用它的功能我們要調(diào)用QuickServer的startQSAdminServer()方法。QSAdminServer運行的默認(rèn)端口是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端口。但是它怎樣進(jìn)行驗證呢?如果沒有一個外在的驗證器,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,因為我們使用默認(rèn)的用戶名密碼,直接點擊"Login"登錄。
    ??? 登錄后界面將會顯示歡迎及登錄成功信息。現(xiàn)在可以選擇發(fā)送命令的目標(biāo)服務(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"以重新加載目標(biāo)服務(wù)器的配置。修改好參數(shù),然后點擊"Save"就可以了。部分參數(shù)的生效需要重啟服務(wù)器,不過這樣不會斷開與客戶端的連接。

    2.?添加自己的命令
    ??? 前面講過如果我們想改變一些服務(wù)器的屬性,我們無須修改已有的代碼或重啟服務(wù)器,我們可以添加自己的命令來管理服務(wù)器。
    ??? 讓我們用一個例子來演示這個功能。當(dāng)用戶發(fā)送"What's interest"(利息是多少)時,我們將要顯示當(dāng)前的利率。這個數(shù)字存貯在一個對象中,如果需要的話,無須重啟服務(wù)器就可以改變它。我們說它是可變的并且當(dāng)服務(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];
    ??? 如果進(jìn)程獲得了一個命令,返回true,否則返回false,并指明QSAdminServer的默認(rèn)命令處理器將被用來處理命令。同樣的技術(shù)將被使用于覆寫QSAdminServer命令處理器的默認(rèn)命令。

    ??? 讓我們告訴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 }


    ??? 編譯代碼,并運行。現(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默認(rèn)已可以使用日志器,但是除了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(),如果沒有指定級別,它默認(rèn)使用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,你將看到當(dāng)客戶端連接時控制臺會顯示你的地址。
    ?? 讓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,這里我們沒有指定格式因為默認(rèn)的格式就是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)用
    ??? 當(dā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ù)量,使用文件記錄詳細(xì)的日志,并降低日志的級別。這樣可以改善應(yīng)用的性能。避免使用System.out.println(),用logging代替。ClientHandler中的sendSystemMsg()方法在記錄日志方面很有用。


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

    在前面的章節(jié)里我們擴(kuò)展了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é)尾的字符串。當(dāng)然,在Internet標(biāo)準(zhǔn)協(xié)議里它是最常用的。但有時我們可能需要接收字節(jié)流或Java對象。
    ??? 下面是數(shù)據(jù)模式和數(shù)據(jù)類型,使用它你可以告訴ClientHandler使用哪一種通信模式。
    ??? 數(shù)據(jù)模式用于定義QuickServer和客戶Socket之間的數(shù)據(jù)交換格式。下面是目前支持的三種模式:
    • DataMode.STRING - 這是默認(rèn)的交換模式,在這種模式下你可以接收字符串?dāng)?shù)據(jù)(以<CR><LF>結(jié)尾)
    • ?DataMode.OBJECT - 在這種模式里你可以接收可序列化的Java對象。這種模式僅僅使用在客戶端可以寫java的情況下。
    • ?DataMode.BYTE - 在這種模式下你可以接收客戶端發(fā)送的所有字節(jié),包括<CR>或<LF>或任何其它控制字符。這種模式在處理基于客戶機(jī)或無標(biāo)準(zhǔn)協(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)
    注意:
    ??? 當(dāng)模式為DataMode.OBJECT類型為DataType.IN,調(diào)用將會阻塞,直到客戶端的ObjectOutputStream被寫和頭被刷新。


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

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

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    IT風(fēng)云人物

    文檔

    朋友

    相冊

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

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品国偷自产在线| 国产精品免费观看调教网| 亚洲&#228;v永久无码精品天堂久久 | 久久夜色精品国产噜噜亚洲a| 亚洲免费二区三区| 亚洲成aⅴ人在线观看| 国产精品成人观看视频免费| 亚洲婷婷天堂在线综合| 亚洲视频免费一区| 亚洲综合伊人制服丝袜美腿| 四虎永久在线精品免费网址| jiz zz在亚洲| 成人免费无码精品国产电影| 国产精品久久久久久亚洲小说| 免费真实播放国产乱子伦| 男女作爱免费网站| 亚洲色偷偷偷鲁综合| a级毛片在线免费观看| 亚洲AV无码一区二区二三区入口 | 午夜免费福利在线| 亚洲AV无码一区二区一二区| 四虎影视精品永久免费| 手机永久免费的AV在线电影网| 久久综合亚洲色HEZYO国产| 国产一级高青免费| 亚洲黄网在线观看| 无人影院手机版在线观看免费| 亚洲色www永久网站| 四虎影院永久免费观看| 久久久久久久国产免费看| 亚洲AV乱码一区二区三区林ゆな | 久久久青草青青亚洲国产免观| 99视频在线看观免费| 亚洲国产区男人本色在线观看| 国产免费啪嗒啪嗒视频看看| 一级毛片成人免费看a| 亚洲AV无码专区在线播放中文| 免费无码VA一区二区三区| 中文字幕亚洲精品无码| 啊灬啊灬别停啊灬用力啊免费看| 中文字幕看片在线a免费|