dubbo系列 - telnet
Dubbo
服务器判断如果接受到的请求时候String
类型时,会调到TelnetHandlerAdapter#telnet
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| public class TelnetHandlerAdapter extends ChannelHandlerAdapter implements TelnetHandler {
private final ExtensionLoader<TelnetHandler> extensionLoader = ExtensionLoader.getExtensionLoader(TelnetHandler.class);
@Override public String telnet(Channel channel, String message) throws RemotingException { String prompt = channel.getUrl().getParameterAndDecoded(Constants.PROMPT_KEY, Constants.DEFAULT_PROMPT); boolean noprompt = message.contains("--no-prompt"); message = message.replace("--no-prompt", ""); StringBuilder buf = new StringBuilder(); message = message.trim(); String command; if (message.length() > 0) { int i = message.indexOf(' '); if (i > 0) { command = message.substring(0, i).trim(); message = message.substring(i + 1).trim(); } else { command = message; message = ""; } } else { command = ""; } if (command.length() > 0) { if (extensionLoader.hasExtension(command)) { if (commandEnabled(channel.getUrl(), command)) { try { String result = extensionLoader.getExtension(command).telnet(channel, message); if (result == null) { return null; } buf.append(result); } catch (Throwable t) { buf.append(t.getMessage()); } } else { buf.append("Command: "); buf.append(command); buf.append(" disabled"); } } else { buf.append("Unsupported command: "); buf.append(command); } } if (buf.length() > 0) { buf.append("\r\n"); } if (prompt != null && prompt.length() > 0 && !noprompt) { buf.append(prompt); } return buf.toString(); }
private boolean commandEnabled(URL url, String command) { boolean commandEnable = false; String supportCommands = url.getParameter(Constants.TELNET); if (StringUtils.isEmpty(supportCommands)) { commandEnable = true; } else { String[] commands = Constants.COMMA_SPLIT_PATTERN.split(supportCommands); for (String c : commands) { if (command.equals(c)) { commandEnable = true; break; } } } return commandEnable; }
}
|
TelnetHandlerAdapter
解析命令,然后通过SPI来调到具体的TelnetHandler
实现类。
通过SPI的配置文件可以知道Dubbo
一共有12个TelnetHandler
扩展:
clear=com.alibaba.dubbo.remoting.telnet.support.command.ClearTelnetHandler
exit=com.alibaba.dubbo.remoting.telnet.support.command.ExitTelnetHandler
help=com.alibaba.dubbo.remoting.telnet.support.command.HelpTelnetHandler
status=com.alibaba.dubbo.remoting.telnet.support.command.StatusTelnetHandler
log=com.alibaba.dubbo.remoting.telnet.support.command.LogTelnetHandler
ls=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.ListTelnetHandler
ps=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.PortTelnetHandler
cd=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.ChangeTelnetHandler
pwd=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.CurrentTelnetHandler
invoke=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.InvokeTelnetHandler
trace=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.TraceTelnetHandler
count=com.alibaba.dubbo.rpc.protocol.dubbo.telnet.CountTelnetHandler
看一下ListTelnetHandler
的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| @Activate @Help(parameter = "[-l] [service]", summary = "List services and methods.", detail = "List services and methods.") public class ListTelnetHandler implements TelnetHandler {
@Override public String telnet(Channel channel, String message) { StringBuilder buf = new StringBuilder(); String service = null; boolean detail = false; if (message.length() > 0) { String[] parts = message.split("\\s+"); for (String part : parts) { if ("-l".equals(part)) { detail = true; } else { if (service != null && service.length() > 0) { return "Invaild parameter " + part; } service = part; } } } else { service = (String) channel.getAttribute(ChangeTelnetHandler.SERVICE_KEY); if (service != null && service.length() > 0) { buf.append("Use default service " + service + ".\r\n"); } } if (service == null || service.length() == 0) { for (Exporter<?> exporter : DubboProtocol.getDubboProtocol().getExporters()) { if (buf.length() > 0) { buf.append("\r\n"); } buf.append(exporter.getInvoker().getInterface().getName()); if (detail) { buf.append(" -> "); buf.append(exporter.getInvoker().getUrl()); } } } else { Invoker<?> invoker = null; for (Exporter<?> exporter : DubboProtocol.getDubboProtocol().getExporters()) { if (service.equals(exporter.getInvoker().getInterface().getSimpleName()) || service.equals(exporter.getInvoker().getInterface().getName()) || service.equals(exporter.getInvoker().getUrl().getPath())) { invoker = exporter.getInvoker(); break; } } if (invoker != null) { Method[] methods = invoker.getInterface().getMethods(); for (Method method : methods) { if (buf.length() > 0) { buf.append("\r\n"); } if (detail) { buf.append(ReflectUtils.getName(method)); } else { buf.append(method.getName()); } } } else { buf.append("No such service " + service); } } return buf.toString(); }
}
|