|
@@ -1,46 +1,67 @@
|
|
|
package com.xiaobao.gateway.protocol.proxy.reverse;
|
|
package com.xiaobao.gateway.protocol.proxy.reverse;
|
|
|
|
|
|
|
|
|
|
+import com.xiaobao.gateway.protocol.dto.MediaServerDTO;
|
|
|
|
|
+import io.netty.bootstrap.Bootstrap;
|
|
|
import io.netty.buffer.ByteBuf;
|
|
import io.netty.buffer.ByteBuf;
|
|
|
-import io.netty.buffer.Unpooled;
|
|
|
|
|
-import io.netty.channel.Channel;
|
|
|
|
|
-import io.netty.channel.ChannelFutureListener;
|
|
|
|
|
-import io.netty.channel.ChannelHandlerContext;
|
|
|
|
|
-import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
|
|
|
|
|
+import io.netty.channel.*;
|
|
|
|
|
+import io.netty.channel.socket.SocketChannel;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
public class ReverseProxyServerInHandler extends ChannelInboundHandlerAdapter {
|
|
public class ReverseProxyServerInHandler extends ChannelInboundHandlerAdapter {
|
|
|
- private ReverseProxyHolder reverseProxyHolder;
|
|
|
|
|
|
|
+ private static final Map<Integer, MediaServerDTO> mediaRouteTable = MediaServerDTO.getRouteTable();
|
|
|
|
|
+
|
|
|
|
|
+ private Channel outboundChannel;
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public void channelActive(ChannelHandlerContext ctx) {
|
|
|
|
|
- this.reverseProxyHolder = new ReverseProxyHolder(ctx);
|
|
|
|
|
|
|
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
|
|
|
|
+ ctx.read();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
|
|
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
|
|
|
- if (msg instanceof ByteBuf && reverseProxyHolder != null) {
|
|
|
|
|
|
|
+ if (msg instanceof ByteBuf) {
|
|
|
ByteBuf in = (ByteBuf) msg;
|
|
ByteBuf in = (ByteBuf) msg;
|
|
|
- if (in.readableBytes() < 6) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- // 标记读索引位置
|
|
|
|
|
- in.markReaderIndex();
|
|
|
|
|
// 读取消息长度(4 字节)
|
|
// 读取消息长度(4 字节)
|
|
|
int len = in.readInt();
|
|
int len = in.readInt();
|
|
|
// 读取消息类型(2 字节)
|
|
// 读取消息类型(2 字节)
|
|
|
- short identifier = in.readShort();
|
|
|
|
|
- // 获取路由通道
|
|
|
|
|
- Channel outboundChannel = reverseProxyHolder.getChannel(identifier);
|
|
|
|
|
|
|
+ int identifier = in.readShort();
|
|
|
if (outboundChannel == null) {
|
|
if (outboundChannel == null) {
|
|
|
- ctx.fireChannelRead(msg);
|
|
|
|
|
- } else {
|
|
|
|
|
- // 检查是否有足够的字节来读取消息体
|
|
|
|
|
- if (in.readableBytes() < len) {
|
|
|
|
|
- // 重置读索引
|
|
|
|
|
- in.resetReaderIndex();
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ if (mediaRouteTable.containsKey(identifier)) {
|
|
|
|
|
+ MediaServerDTO server = mediaRouteTable.get(identifier);
|
|
|
|
|
+ Channel inboundChannel = ctx.channel();
|
|
|
|
|
+ Bootstrap b = new Bootstrap();
|
|
|
|
|
+ b.group(inboundChannel.eventLoop())
|
|
|
|
|
+ .channel(inboundChannel.getClass())
|
|
|
|
|
+ .handler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
|
|
+ ChannelPipeline pipeline = ch.pipeline();
|
|
|
|
|
+ pipeline.addLast(new ReverseProxyClientInHandler(inboundChannel, server));
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .option(ChannelOption.AUTO_READ, false);
|
|
|
|
|
+ ChannelFuture f = b.connect(server.getRemoteHost(), server.getRemotePort());
|
|
|
|
|
+ outboundChannel = f.channel();
|
|
|
|
|
+ f.addListener((ChannelFutureListener) future -> {
|
|
|
|
|
+ if (future.isSuccess()) {
|
|
|
|
|
+ ByteBuf body = ctx.alloc().buffer(len);
|
|
|
|
|
+ in.readBytes(body);
|
|
|
|
|
+ outboundChannel.writeAndFlush(body).addListener((ChannelFutureListener) writeFuture -> {
|
|
|
|
|
+ if (writeFuture.isSuccess()) {
|
|
|
|
|
+ inboundChannel.read();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ future.channel().close();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ inboundChannel.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ctx.close();
|
|
|
}
|
|
}
|
|
|
|
|
+ } else {
|
|
|
// 读取消息体
|
|
// 读取消息体
|
|
|
ByteBuf body = ctx.alloc().buffer(len);
|
|
ByteBuf body = ctx.alloc().buffer(len);
|
|
|
in.readBytes(body);
|
|
in.readBytes(body);
|
|
@@ -58,29 +79,4 @@ public class ReverseProxyServerInHandler extends ChannelInboundHandlerAdapter {
|
|
|
ctx.fireChannelRead(msg);
|
|
ctx.fireChannelRead(msg);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public void channelInactive(ChannelHandlerContext ctx) {
|
|
|
|
|
- if (reverseProxyHolder != null) {
|
|
|
|
|
- Map<Integer, Channel> connections = reverseProxyHolder.getConnections();
|
|
|
|
|
- for (Channel outboundChannel : connections.values()) {
|
|
|
|
|
- closeOnFlush(outboundChannel);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
|
|
|
|
- cause.printStackTrace();
|
|
|
|
|
- closeOnFlush(ctx.channel());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Closes the specified channel after all queued write requests are flushed.
|
|
|
|
|
- */
|
|
|
|
|
- static void closeOnFlush(Channel ch) {
|
|
|
|
|
- if (ch.isActive()) {
|
|
|
|
|
- ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|