⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commandhandler.java

📁 一个用java编写的服务器,对于学习网络编程的人来说是个很好的例子
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * This file is part of the QuickServer library 
 * Copyright (C) QuickServer.org
 *
 * Use, modification, copying and distribution of this software is subject to
 * the terms and conditions of the GNU Lesser General Public License. 
 * You should have received a copy of the GNU LGP License along with this 
 * library; if not, you can download a copy from <http://www.quickserver.org/>.
 *
 * For questions, suggestions, bug-reports, enhancement-requests etc.
 * visit http://www.quickserver.org
 *
 */

package org.quickserver.net.qsadmin;

import java.net.*;
import java.io.*;
import java.util.StringTokenizer;

import org.quickserver.net.server.ClientCommandHandler;
import org.quickserver.net.server.ClientEventHandler;
import org.quickserver.net.server.ClientHandler;
import org.quickserver.net.server.QuickServer;
import org.quickserver.net.AppException;

import java.util.logging.*;

import org.quickserver.util.*;
import org.quickserver.util.pool.thread.*;
import java.util.*;
import org.quickserver.util.pool.*;
import org.apache.commons.pool.ObjectPool;
import org.quickserver.net.server.ClientIdentifier;

/**
 * ClientCommandHandler for QSAdminServer.
 * <p>
 * = Protocol =<br>
 * Each response starts with a status.
 * <ul>
 *  <li>+OK = Success
 *  <li>-ERR = Failed
 * </ul>
 * If response if one lined then it follows the status.
 * Else You will get "info follows" as the first line
 * followed by with many lines of response ending by a 
 * dot in a line by itself. i.e.,  &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;<br>
 * Command supported are give below .. [ Note: &lt;&lt;target&gt;&gt; = server|self ]
 * <br>&nbsp;<br>
 * <table align="center" border=1>
 * <tr><th>Command</th><th>Param</th><th>Effect</th></tr>
 * <tr><td>start</td><td>&lt;&lt;target&gt;&gt;</td><td>Starts target.</td></tr>
 * <tr><td>stop</td><td>&lt;&lt;target&gt;&gt;</td><td>Stops target.</td></tr>
 * <tr><td>restart</td><td>&lt;&lt;target&gt;&gt;</td><td>=stop+start command</td></tr>
 * <tr><td>shutdown</td><td>&nbsp;</td><td>Stops server and self. </td></tr>
 * <tr><td>kill or exit</td><td>&nbsp;</td><td>Stops server and self and kill all threads. </td></tr>
 * <tr><td>info</td><td>&lt;&lt;target&gt;&gt;</td><td>Information about target.</td></tr>
 * <tr><td>noclient</td><td>&lt;&lt;target&gt;&gt;</td><td>No Client connected to the target.</td></tr>
 * <tr><td>running</td><td>&lt;&lt;target&gt;&gt;</td><td>Checks if target is running.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; maxClient</td><td>Gets max no of client for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; port</td><td>Gets port for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; maxAuthTryMsg</td><td>Gets maxAuthTryMsg for the target. </td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientCommandHandler</td><td>Gets ClientCommandHandler class for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientAuthenticationHandler</td><td>Gets ClientAuthenticationHandler class for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientData</td><td>Gets ClientData class for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; timeout</td><td>Gets timeout set for clients for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; maxClient &lt;&lt;value&gt;&gt;</td><td>Sets max no of client for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; port &lt;&lt;value&gt;&gt;</td><td>Sets port for the target.*</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; maxAuthTryMsg &lt;&lt;value&gt;&gt;</td><td>Sets maxAuthTryMsg for the target. *</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientCommandHandler &lt;&lt;value&gt;&gt;</td><td>Sets ClientCommandHandler class for the target. *</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientAuthenticationHandler &lt;&lt;value&gt;&gt;</td><td>Sets ClientAuthenticationHandler class for the target. *</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientData &lt;&lt;value&gt;&gt;</td><td>Sets ClientData class for the target. *</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; timeout &lt;&lt;value&gt;&gt;</td><td>Sets timeout set for clients for the target. *</td></tr>
 * <tr><td>version</td><td>&nbsp;</td><td>Gets the version of the QuickServer library used.</td></tr>
 * <tr><td>quit</td><td>&nbsp;</td><td>Close session.</td></tr>
 * <tr><td colspan=3>New Command in v1.2 </td></tr>
 * <tr><td>get</td><td>self plugin</td><td>Gets pluggable command handler for QsAdminServer. *</td></tr>
 * <tr><td>set</td><td>self plugin &lt;&lt;full class name&gt;&gt;</td><td>Sets Pluggable command handler for QsAdminServer. *</td></tr>
 * <tr><td colspan=3>New Command in v1.3 </td></tr>
 * <tr><td>suspendService</td><td>&lt;&lt;target&gt;&gt;</td><td>Suspends target.</td></tr>
 * <tr><td>resumeService</td><td>&lt;&lt;target&gt;&gt;</td><td>Resume target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; maxAuthTry</td><td>Gets maxAuthTry for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; maxAuthTry</td><td>Sets maxAuthTry for the target.*</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientObjectHandler</td><td>Gets ClientObjectHandler class for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientObjectHandler</td><td>Sets ClientObjectHandler class for the target.*</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; timeoutMsg</td><td>Gets timeout Message for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; timeoutMsg</td><td>Sets timeout Message for the target.*</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; serviceState</td><td>Gets Service State for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; consoleLoggingFormatter</td><td>Sets consoleLoggingFormatter for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; consoleLoggingFormatter</td><td>Sets consoleLoggingFormatter for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; consoleLoggingLevel</td><td>Sets consoleLoggingLevel for the target. <br>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; consoleLoggingLevel</td><td>Sets consoleLoggingLevel for the target. <br>
 * [<code>SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST<code>]</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; maxClientMsg</td><td>Sets maxClientMsg for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; maxClientMsg</td><td>Gets maxClientMsg for the target.</td></tr>
 * <tr><td colspan=3>New Command in v1.3.1 </td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; loggingLevel</td><td>Sets LoggingLevel for the target. <br>
 * [<code>SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST<code>]</td></tr>
 * <tr><td colspan=3>New Command in v1.3.2 </td></tr>
 * <tr><td>memoryInfo</td><td>&nbsp;</td><td>Memory Information {Total:Used:Max}</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; communicationLogging</td><td>Sets communication logging flag for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; communicationLogging</td><td>Gets communication logging flag for the target.</td></tr>

 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; objectPoolConfig-maxActive</td><td>Sets maxActive of objectPoolConfig for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; objectPoolConfig-maxActive</td><td>Gets maxActive of objectPoolConfig for the target.</td></tr>

 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; objectPoolConfig-maxIdle</td><td>Sets maxIdle of objectPoolConfig for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; objectPoolConfig-maxIdle</td><td>Gets maxIdle of objectPoolConfig for the target.</td></tr>
 *
 * <tr><td colspan=3>New Command in v1.4.5 </td></tr>
 * <tr><td>all-pool-info</td><td>&lt;&lt;target&gt;&gt;</td><td>Gives stats of all pools for the target.</td></tr>
 * <tr><td>client-thread-pool-dump</td><td>&lt;&lt;target&gt;&gt;</td><td>Gives dump of all threads in pool for the target.</td></tr>
 * <tr><td>start</td><td>&lt;&lt;console&gt;&gt;</td><td>Starts console shell.</td></tr>
 * <tr><td>stop</td><td>&lt;&lt;console&gt;&gt;</td><td>Stops console shell.</td></tr>
 *
 * <tr><td colspan=3>New Command in v1.4.6 </td></tr>
 * <tr><td>client-handler-pool-dump</td><td>&lt;&lt;target&gt;&gt;</td><td>Gives dump of all ClientHandler in pool for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientEventHandler</td><td>Gets ClientEventHandler class for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientEventHandler &lt;&lt;value&gt;&gt;</td><td>Sets ClientEventHandler class for the target. *</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientWriteHandler</td><td>Gets ClientWriteHandler class for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientWriteHandler &lt;&lt;value&gt;&gt;</td><td>Sets ClientWriteHandler class for the target. *</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; clientExtendedEventHandler</td><td>Gets ClientExtendedEventHandler class for the target.</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; clientExtendedEventHandler &lt;&lt;value&gt;&gt;</td><td>Sets ClientExtendedEventHandler class for the target. *</td></tr>
 * <tr><td>set</td><td>&lt;&lt;target&gt;&gt; objectPoolConfig-initSize</td><td>Sets initSize of objectPoolConfig for the target.</td></tr>
 * <tr><td>get</td><td>&lt;&lt;target&gt;&gt; objectPoolConfig-initSize</td><td>Gets initSize of objectPoolConfig for the target.</td></tr>
 *
 * <tr><td colspan=3>* = Take effect after a restart command.<br>
 *      value if set null then key will be set to <code>null</code>
 *     </td></tr>
 * </table>
 * <br>Note: 
 * <ul>
 * <li>Stopping the QuickServer will not disconnect any client connect to it, since 
 * client connections are handled by different thread.
 * <li><code>restart</code> and <code>start</code> response just indicate only 
 * if command was sent. Do check the state of the target using 
 * <code>running</code> command to see if server was started successful.
 * <li>Demo code examples\EchoServer shows the use of QsAdminServer to control itself.
 * </ul>
 * Eg: <br>
 * <BLOCKQUOTE>
 *  noClient server<br>
 *  noClient self<br>
 *  get server maxClient<br>
 *  set server maxClient 10
 * </BLOCKQUOTE>
 * </p>
 * @since 1.1
 */
public class CommandHandler implements ClientCommandHandler, ClientEventHandler {
	private static Logger logger = Logger.getLogger(CommandHandler.class.getName());

	private CommandPlugin plugin;
	private Runtime runtime;
	StringBuffer temp = new StringBuffer();

	//-- ClientEventHandler
	public void gotConnected(ClientHandler handler)
		throws SocketTimeoutException, IOException {
		logger.fine("Connection opened : " + handler.getHostAddress());

		handler.sendClientMsg("+OK +++++++++++++++++++++++++++++++++");
		handler.sendClientMsg("+OK   Welcome to QsAdminServer v 1.0 ");
		handler.sendClientMsg("+OK +++++++++++++++++++++++++++++++++");

		//v.2
		if(plugin==null || runtime==null) {
			plugin = (CommandPlugin)
				handler.getServer().getStoreObjects()[1];
			//v1.3.2
			runtime = Runtime.getRuntime();
		}
	}

	public void lostConnection(ClientHandler handler) 
			throws IOException {
		logger.fine("Connection lost : " + handler.getHostAddress());
	}
	public void closingConnection(ClientHandler handler) 
			throws IOException {
		logger.fine("Connection closing : " + handler.getHostAddress());
	}
	//-- ClientEventHandler

	public void handleCommand(ClientHandler handler, String command)
			throws SocketTimeoutException, IOException {
		if(command==null || command.trim().equals("")) {
			handler.sendClientMsg("-ERR No command");
			return;
		}
		
		//v1.2 - plugin
		if( plugin != null && plugin.handleCommand(handler,command) ) {
			logger.fine("Handled by plugin.");
			return;
		}
		QSAdminServer adminServer = (QSAdminServer)
			handler.getServer().getStoreObjects()[2];

		StringTokenizer st = new StringTokenizer(command," ");
		String cmd = null;
		cmd = st.nextToken().toLowerCase();
		String param[] = new String[st.countTokens()];
		
		QuickServer target = null;		
		for (int i=0;st.hasMoreTokens();i++)
			param[i] = st.nextToken();

		if(command.equals("start console")) { /*v1.4.5*/
			QSAdminShell.getInstance(
				(QuickServer) handler.getServer().getStoreObjects()[0], null);
			handler.sendClientMsg("+OK QSAdminShell is started.");
			return;
		} else if(command.equals("stop console")) { /*v1.4.5*/
			QSAdminShell shell = QSAdminShell.getInstance(null, null);
			if(shell!=null) {
				try {
					shell.stopShell();
				} catch(Exception err) {
					handler.sendClientMsg("-ERR Error stopping QSAdminShell: "+err);
				}				
				handler.sendClientMsg("+OK QSAdminShell is stopped.");
			} else {
				handler.sendClientMsg("-ERR QSAdminShell is not running.");
			}
			return;
		}

		if(param.length > 0) {
			if( param[0].equals("server") )
				target = (QuickServer) handler.getServer().getStoreObjects()[0];
			else if( param[0].equals("self") )
				target = handler.getServer();
			else {
				handler.sendClientMsg("-ERR Bad <<target>> : "+param[0]);
				return;
			}
		}
 
		if(cmd.equals("help")) {
			handler.sendClientMsg("+OK info follows"+"\r\n"+
				"Refer Api Docs for org.quickserver.net.qsadmin.CommandHandler");
			handler.sendClientMsg(".");
			return;
		} else if(cmd.equals("quit")) {
			handler.sendClientMsg("+OK Bye ;-)");
			handler.closeConnection();
			return;
		} else if(cmd.equals("shutdown")) {
			try	{
				QuickServer controlServer = 
					(QuickServer) handler.getServer().getStoreObjects()[0];
				if(controlServer!=null && controlServer.isClosed()==false) {
					controlServer.stopServer();
				}
				if(handler.getServer()!=null && handler.getServer().isClosed()==false) {
					handler.getServer().stopServer();
				}

				QSAdminShell shell = QSAdminShell.getInstance(null, null);
				if(shell!=null) {
					try {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -