diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/HttpTermServer.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/HttpTermServer.java index 9caf07aa2..002305b17 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/HttpTermServer.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/HttpTermServer.java @@ -4,10 +4,10 @@ import com.taobao.arthas.core.shell.future.Future; import com.taobao.arthas.core.shell.handlers.Handler; import com.taobao.arthas.core.shell.term.Term; import com.taobao.arthas.core.shell.term.TermServer; +import com.taobao.arthas.core.shell.term.impl.http.NettyWebsocketTtyBootstrap; import com.taobao.arthas.core.util.LogUtil; import com.taobao.middleware.logger.Logger; import io.termd.core.function.Consumer; -import io.termd.core.http.netty.NettyWebsocketTtyBootstrap; import io.termd.core.tty.TtyConnection; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/DirectoryBrowser.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java similarity index 98% rename from core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/DirectoryBrowser.java rename to core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java index eae6e12b5..98e50d429 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/DirectoryBrowser.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java @@ -1,4 +1,4 @@ -package com.taobao.arthas.core.shell.term.impl.httptelnet; +package com.taobao.arthas.core.shell.term.impl.http; import java.io.File; import java.io.FileInputStream; diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/HttpRequestHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java similarity index 98% rename from core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/HttpRequestHandler.java rename to core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java index 20b9a76af..eb98a4e4a 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/HttpRequestHandler.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java @@ -1,4 +1,4 @@ -package com.taobao.arthas.core.shell.term.impl.httptelnet; +package com.taobao.arthas.core.shell.term.impl.http; import java.io.File; import java.io.InputStream; diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/NettyWebsocketTtyBootstrap.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/NettyWebsocketTtyBootstrap.java new file mode 100644 index 000000000..fefffce62 --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/NettyWebsocketTtyBootstrap.java @@ -0,0 +1,106 @@ +package com.taobao.arthas.core.shell.term.impl.http; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import io.netty.util.concurrent.ImmediateEventExecutor; +import io.termd.core.function.Consumer; +import io.termd.core.tty.TtyConnection; +import io.termd.core.util.CompletableFuture; +import io.termd.core.util.Helper; + +/** + * Convenience class for quickly starting a Netty Tty server. + * + * @author Julien Viet + */ +public class NettyWebsocketTtyBootstrap { + + private final ChannelGroup channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); + private String host; + private int port; + private EventLoopGroup group; + private Channel channel; + + public NettyWebsocketTtyBootstrap() { + this.host = "localhost"; + this.port = 8080; + } + + public String getHost() { + return host; + } + + public NettyWebsocketTtyBootstrap setHost(String host) { + this.host = host; + return this; + } + + public int getPort() { + return port; + } + + public NettyWebsocketTtyBootstrap setPort(int port) { + this.port = port; + return this; + } + + public void start(Consumer handler, final Consumer doneHandler) { + group = new NioEventLoopGroup(); + + ServerBootstrap b = new ServerBootstrap(); + b.group(group).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new TtyServerInitializer(channelGroup, handler)); + + final ChannelFuture f = b.bind(host, port); + f.addListener(new GenericFutureListener>() { + @Override + public void operationComplete(Future future) throws Exception { + if (future.isSuccess()) { + channel = f.channel(); + doneHandler.accept(null); + } else { + doneHandler.accept(future.cause()); + } + } + }); + } + + public CompletableFuture start(Consumer handler) { + CompletableFuture fut = new CompletableFuture(); + start(handler, Helper.startedHandler(fut)); + return fut; + } + + public void stop(final Consumer doneHandler) { + if (channel != null) { + channel.close(); + } + + channelGroup.close().addListener(new GenericFutureListener>() { + @Override + public void operationComplete(Future future) throws Exception { + try { + doneHandler.accept(future.cause()); + } finally { + group.shutdownGracefully(); + } + } + }); + } + + public CompletableFuture stop() { + CompletableFuture fut = new CompletableFuture(); + stop(Helper.stoppedHandler(fut)); + return fut; + } +} diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/TtyServerInitializer.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/TtyServerInitializer.java new file mode 100644 index 000000000..1dacb1f7a --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/TtyServerInitializer.java @@ -0,0 +1,40 @@ +package com.taobao.arthas.core.shell.term.impl.http; + +import java.io.File; + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.stream.ChunkedWriteHandler; +import io.termd.core.function.Consumer; +import io.termd.core.tty.TtyConnection; + + +/** + * @author Julien Viet + */ +public class TtyServerInitializer extends ChannelInitializer { + + private final ChannelGroup group; + private final Consumer handler; + + public TtyServerInitializer(ChannelGroup group, Consumer handler) { + this.group = group; + this.handler = handler; + } + + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast(new HttpServerCodec()); + pipeline.addLast(new ChunkedWriteHandler()); + pipeline.addLast(new HttpObjectAggregator(64 * 1024)); + pipeline.addLast(new HttpRequestHandler("/ws", new File("arthas-output"))); + pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); + pipeline.addLast(new TtyWebSocketFrameHandler(group, handler)); + } +} diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/TtyWebSocketFrameHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/TtyWebSocketFrameHandler.java similarity index 98% rename from core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/TtyWebSocketFrameHandler.java rename to core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/TtyWebSocketFrameHandler.java index b897525c9..cf7c6a32c 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/TtyWebSocketFrameHandler.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/TtyWebSocketFrameHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.taobao.arthas.core.shell.term.impl.httptelnet; +package com.taobao.arthas.core.shell.term.impl.http; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/package-info.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/package-info.java new file mode 100644 index 000000000..269bc5945 --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/package-info.java @@ -0,0 +1 @@ +package com.taobao.arthas.core.shell.term.impl.http; \ No newline at end of file diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/ProtocolDetectHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/ProtocolDetectHandler.java index 4399eb2dc..4ca8ea6f5 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/ProtocolDetectHandler.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/httptelnet/ProtocolDetectHandler.java @@ -3,6 +3,9 @@ package com.taobao.arthas.core.shell.term.impl.httptelnet; import java.io.File; import java.util.concurrent.TimeUnit; +import com.taobao.arthas.core.shell.term.impl.http.HttpRequestHandler; +import com.taobao.arthas.core.shell.term.impl.http.TtyWebSocketFrameHandler; + import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; diff --git a/core/src/main/resources/com/taobao/arthas/core/http/web-console.js b/core/src/main/resources/com/taobao/arthas/core/http/web-console.js index fa9f52b01..8983073bd 100644 --- a/core/src/main/resources/com/taobao/arthas/core/http/web-console.js +++ b/core/src/main/resources/com/taobao/arthas/core/http/web-console.js @@ -12,6 +12,9 @@ $(function () { if (port != '' && port != null) { $('#port').val(port); } + if (port == null && location.port == "8563") { + $('#port').val(8563); + } startConnect(true); }); diff --git a/pom.xml b/pom.xml index c4afc3bb1..dbdd1a86f 100644 --- a/pom.xml +++ b/pom.xml @@ -107,7 +107,7 @@ com.alibaba.middleware termd-core - 1.1.7.6 + 1.1.7.7 com.alibaba.middleware