mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
support http and telnet in one port. #316
This commit is contained in:
+3
-3
@@ -15,7 +15,6 @@ import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import io.netty.util.concurrent.ScheduledFuture;
|
||||
import io.termd.core.function.Consumer;
|
||||
import io.termd.core.function.Supplier;
|
||||
import io.termd.core.http.netty.TtyWebSocketFrameHandler;
|
||||
import io.termd.core.telnet.TelnetHandler;
|
||||
import io.termd.core.telnet.netty.TelnetChannelHandler;
|
||||
import io.termd.core.tty.TtyConnection;
|
||||
@@ -52,7 +51,7 @@ public class ProtocolDetectHandler extends ChannelInboundHandlerAdapter {
|
||||
ctx.fireChannelActive(); // trigger TelnetChannelHandler init
|
||||
}
|
||||
|
||||
}, 500, TimeUnit.MILLISECONDS);
|
||||
}, 1000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,9 +82,10 @@ public class ProtocolDetectHandler extends ChannelInboundHandlerAdapter {
|
||||
pipeline.addLast(new HttpRequestHandler("/ws", new File("arthas-output")));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
|
||||
pipeline.addLast(new TtyWebSocketFrameHandler(channelGroup, ttyConnectionFactory));
|
||||
ctx.fireChannelActive();
|
||||
}
|
||||
ctx.fireChannelRead(in);
|
||||
pipeline.remove(this);
|
||||
ctx.fireChannelRead(in);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2015 Julien Viet
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.taobao.arthas.core.shell.term.impl.httptelnet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.group.ChannelGroup;
|
||||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||
import io.termd.core.function.Consumer;
|
||||
import io.termd.core.http.HttpTtyConnection;
|
||||
import io.termd.core.tty.TtyConnection;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
|
||||
*/
|
||||
public class TtyWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
|
||||
|
||||
private final ChannelGroup group;
|
||||
private final Consumer<TtyConnection> handler;
|
||||
private ChannelHandlerContext context;
|
||||
private HttpTtyConnection conn;
|
||||
|
||||
public TtyWebSocketFrameHandler(ChannelGroup group, Consumer<TtyConnection> handler) {
|
||||
this.group = group;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
super.channelActive(ctx);
|
||||
context = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
|
||||
ctx.pipeline().remove(HttpRequestHandler.class);
|
||||
group.add(ctx.channel());
|
||||
conn = new HttpTtyConnection() {
|
||||
@Override
|
||||
protected void write(byte[] buffer) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(buffer);
|
||||
if (context != null) {
|
||||
context.writeAndFlush(new TextWebSocketFrame(byteBuf));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void schedule(Runnable task, long delay, TimeUnit unit) {
|
||||
if (context != null) {
|
||||
context.executor().schedule(task, delay, unit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable task) {
|
||||
if (context != null) {
|
||||
context.executor().execute(task);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
handler.accept(conn);
|
||||
} else {
|
||||
super.userEventTriggered(ctx, evt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
HttpTtyConnection tmp = conn;
|
||||
context = null;
|
||||
conn = null;
|
||||
if (tmp != null) {
|
||||
Consumer<Void> closeHandler = tmp.getCloseHandler();
|
||||
if (closeHandler != null) {
|
||||
closeHandler.accept(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
|
||||
conn.writeToDecoder(msg.text());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user