diff --git a/net/src/main/java/com/zfoo/net/core/proxy/ReverseProxyServer.java b/net/src/main/java/com/zfoo/net/core/proxy/ProxyTcpServer.java similarity index 84% rename from net/src/main/java/com/zfoo/net/core/proxy/ReverseProxyServer.java rename to net/src/main/java/com/zfoo/net/core/proxy/ProxyTcpServer.java index 2b0f2435..09b35f4d 100644 --- a/net/src/main/java/com/zfoo/net/core/proxy/ReverseProxyServer.java +++ b/net/src/main/java/com/zfoo/net/core/proxy/ProxyTcpServer.java @@ -15,8 +15,8 @@ package com.zfoo.net.core.proxy; import com.zfoo.net.core.AbstractServer; import com.zfoo.net.core.HostAndPort; +import com.zfoo.net.core.proxy.handler.ProxyCodecHandler; import com.zfoo.net.handler.ServerRouteHandler; -import com.zfoo.net.handler.codec.tcp.TcpCodecHandler; import com.zfoo.net.handler.idle.ServerIdleHandler; import io.netty.channel.socket.SocketChannel; import io.netty.handler.timeout.IdleStateHandler; @@ -24,9 +24,9 @@ import io.netty.handler.timeout.IdleStateHandler; /** * @author jaysunxiao */ -public class ReverseProxyServer extends AbstractServer { +public class ProxyTcpServer extends AbstractServer { - public ReverseProxyServer(HostAndPort host) { + public ProxyTcpServer(HostAndPort host) { super(host); } @@ -34,7 +34,7 @@ public class ReverseProxyServer extends AbstractServer { protected void initChannel(SocketChannel channel) throws Exception { channel.pipeline().addLast(new IdleStateHandler(0, 0, 180)); channel.pipeline().addLast(new ServerIdleHandler()); - channel.pipeline().addLast(new TcpCodecHandler()); + channel.pipeline().addLast(new ProxyCodecHandler()); channel.pipeline().addLast(new ServerRouteHandler()); } } diff --git a/net/src/main/java/com/zfoo/net/core/proxy/TunnelClient.java b/net/src/main/java/com/zfoo/net/core/proxy/TunnelClient.java new file mode 100644 index 00000000..4e1ef506 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/TunnelClient.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy; + +import com.zfoo.net.core.AbstractClient; +import com.zfoo.net.core.HostAndPort; +import com.zfoo.net.core.proxy.handler.TunnelClientRouteHandler; +import com.zfoo.net.core.proxy.handler.TunnelClientCodecHandler; +import com.zfoo.net.handler.idle.ClientIdleHandler; +import com.zfoo.net.packet.DecodedPacketInfo; +import io.netty.channel.Channel; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.timeout.IdleStateHandler; + +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * @author jaysunxiao + */ +public class TunnelClient extends AbstractClient { + + public static final CopyOnWriteArrayList tunnels = new CopyOnWriteArrayList<>(); + + public TunnelClient(HostAndPort host) { + super(host); + } + + @Override + protected void initChannel(SocketChannel channel) { + channel.pipeline().addLast(new IdleStateHandler(0, 0, 60)); + channel.pipeline().addLast(new ClientIdleHandler()); + channel.pipeline().addLast(new TunnelClientCodecHandler()); + channel.pipeline().addLast(new TunnelClientRouteHandler()); + } + + public static class DecodedPacketInfo { + + public long sid; + + public Object packet; + + public Object attachment; + + } + +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/TunnelProtocolServer2Client.java b/net/src/main/java/com/zfoo/net/core/proxy/TunnelProtocolServer2Client.java new file mode 100644 index 00000000..c11b5a33 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/TunnelProtocolServer2Client.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * 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.zfoo.net.core.proxy; + +import io.netty.buffer.ByteBuf; + + +/** + * @author jaysunxiao + */ +public class TunnelProtocolServer2Client { + + private long sid; + + private ByteBuf byteBuf; + + public static TunnelProtocolServer2Client valueOf(long sid, ByteBuf byteBuf) { + var tunnelProtocol = new TunnelProtocolServer2Client(); + tunnelProtocol.sid = sid; + tunnelProtocol.byteBuf = byteBuf; + return tunnelProtocol; + } + + public long getSid() { + return sid; + } + + public void setSid(long sid) { + this.sid = sid; + } + + public ByteBuf getByteBuf() { + return byteBuf; + } + + public void setByteBuf(ByteBuf byteBuf) { + this.byteBuf = byteBuf; + } +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/TunnelServer.java b/net/src/main/java/com/zfoo/net/core/proxy/TunnelServer.java new file mode 100644 index 00000000..5fbba793 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/TunnelServer.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy; + +import com.zfoo.net.core.AbstractServer; +import com.zfoo.net.core.HostAndPort; +import com.zfoo.net.core.proxy.handler.TunnelServerCodecHandler; +import com.zfoo.net.core.proxy.handler.TunnelServerRouteHandler; +import com.zfoo.net.handler.idle.ServerIdleHandler; +import io.netty.channel.Channel; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.timeout.IdleStateHandler; + +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * @author jaysunxiao + */ +public class TunnelServer extends AbstractServer { + + public static final CopyOnWriteArrayList tunnels = new CopyOnWriteArrayList<>(); + + public TunnelServer(HostAndPort host) { + super(host); + } + + @Override + protected void initChannel(SocketChannel channel) throws Exception { + channel.pipeline().addLast(new IdleStateHandler(0, 0, 180)); + channel.pipeline().addLast(new ServerIdleHandler()); + channel.pipeline().addLast(new TunnelServerCodecHandler()); + channel.pipeline().addLast(new TunnelServerRouteHandler()); + } +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/handler/ProxyCodecHandler.java b/net/src/main/java/com/zfoo/net/core/proxy/handler/ProxyCodecHandler.java new file mode 100644 index 00000000..465d62e4 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/handler/ProxyCodecHandler.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.handler; + +import com.zfoo.net.core.proxy.TunnelProtocolServer2Client; +import com.zfoo.net.core.proxy.TunnelServer; +import com.zfoo.net.packet.PacketService; +import com.zfoo.net.util.SessionUtils; +import com.zfoo.protocol.util.IOUtils; +import com.zfoo.protocol.util.RandomUtils; +import com.zfoo.protocol.util.StringUtils; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageCodec; + +import java.util.List; + +/** + * @author jaysunxiao + */ +public class ProxyCodecHandler extends ByteToMessageCodec { + + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + // 不够读一个int + if (in.readableBytes() <= PacketService.PACKET_HEAD_LENGTH) { + return; + } + in.markReaderIndex(); + var length = in.readInt(); + + // 如果长度非法,则抛出异常断开连接,按照自己的使用场景指定合适的长度,防止客户端发送超大包占用带宽 + if (length < 0 || length > IOUtils.BYTES_PER_MB) { + throw new IllegalArgumentException(StringUtils.format("illegal packet [length:{}]", length)); + } + + // ByteBuf里的数据太小 + if (in.readableBytes() < length) { + in.resetReaderIndex(); + return; + } + + var sliceByteBuf = in.readSlice(length); + + var session = SessionUtils.getSession(ctx); + var tunnel = RandomUtils.randomEle(TunnelServer.tunnels); + tunnel.writeAndFlush(TunnelProtocolServer2Client.valueOf(session.getSid(), sliceByteBuf)); + } + + @Override + protected void encode(ChannelHandlerContext ctx, TunnelProtocolServer2Client broker, ByteBuf out) { + } + +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelClientCodecHandler.java b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelClientCodecHandler.java new file mode 100644 index 00000000..f10add50 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelClientCodecHandler.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.handler; + +import com.zfoo.net.NetContext; +import com.zfoo.net.core.proxy.TunnelProtocolServer2Client; +import com.zfoo.net.core.proxy.TunnelServer; +import com.zfoo.net.packet.PacketService; +import com.zfoo.protocol.buffer.ByteBufUtils; +import com.zfoo.protocol.util.IOUtils; +import com.zfoo.protocol.util.StringUtils; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * @author jaysunxiao + */ +public class TunnelClientCodecHandler extends ByteToMessageCodec { + + private static final Logger logger = LoggerFactory.getLogger(TunnelClientCodecHandler.class); + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + // 不够读一个int + if (in.readableBytes() <= PacketService.PACKET_HEAD_LENGTH) { + return; + } + in.markReaderIndex(); + var length = in.readInt(); + + // 如果长度非法,则抛出异常断开连接,按照自己的使用场景指定合适的长度,防止客户端发送超大包占用带宽 + if (length < 0 || length > IOUtils.BYTES_PER_MB) { + throw new IllegalArgumentException(StringUtils.format("illegal packet [length:{}]", length)); + } + + // ByteBuf里的数据太小 + if (in.readableBytes() < length) { + in.resetReaderIndex(); + return; + } + + var sliceByteBuf = in.readSlice(length); + + var sid = ByteBufUtils.readLong(sliceByteBuf); + var packetInfo = NetContext.getPacketService().read(sliceByteBuf); + out.add(packetInfo); + } + + @Override + protected void encode(ChannelHandlerContext ctx, TunnelProtocolServer2Client tunnelProtocol, ByteBuf out) { + } + +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelClientRouteHandler.java b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelClientRouteHandler.java new file mode 100644 index 00000000..f8622c40 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelClientRouteHandler.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.handler; + +import com.zfoo.net.NetContext; +import com.zfoo.net.core.proxy.TunnelClient; +import com.zfoo.net.handler.BaseRouteHandler; +import com.zfoo.net.packet.DecodedPacketInfo; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; + +/** + * @author godotg + */ +@ChannelHandler.Sharable +public class TunnelClientRouteHandler extends BaseRouteHandler { + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + TunnelClient.tunnels.add(ctx.channel()); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + super.channelInactive(ctx); + TunnelClient.tunnels.remove(ctx.channel()); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + + DecodedPacketInfo decodedPacketInfo = (DecodedPacketInfo) msg; + } +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelServerCodecHandler.java b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelServerCodecHandler.java new file mode 100644 index 00000000..f25118aa --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelServerCodecHandler.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.handler; + +import com.zfoo.net.NetContext; +import com.zfoo.net.core.proxy.TunnelProtocolServer2Client; +import com.zfoo.net.core.proxy.TunnelServer; +import com.zfoo.net.packet.PacketService; +import com.zfoo.protocol.buffer.ByteBufUtils; +import com.zfoo.protocol.util.IOUtils; +import com.zfoo.protocol.util.StringUtils; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * @author jaysunxiao + */ +public class TunnelServerCodecHandler extends ByteToMessageCodec { + + private static final Logger logger = LoggerFactory.getLogger(TunnelServerCodecHandler.class); + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + // 不够读一个int + if (in.readableBytes() <= PacketService.PACKET_HEAD_LENGTH) { + return; + } + in.markReaderIndex(); + var length = in.readInt(); + + // 如果长度非法,则抛出异常断开连接,按照自己的使用场景指定合适的长度,防止客户端发送超大包占用带宽 + if (length < 0 || length > IOUtils.BYTES_PER_MB) { + throw new IllegalArgumentException(StringUtils.format("illegal packet [length:{}]", length)); + } + + // ByteBuf里的数据太小 + if (in.readableBytes() < length) { + in.resetReaderIndex(); + return; + } + + var sliceByteBuf = in.readSlice(length); + var messageType = sliceByteBuf.readByte(); + if (messageType == -1) { + TunnelServer.tunnels.add(ctx.channel()); + } + + + var packetInfo = NetContext.getPacketService().read(sliceByteBuf); + out.add(packetInfo); + } + + @Override + protected void encode(ChannelHandlerContext ctx, TunnelProtocolServer2Client tunnelProtocol, ByteBuf out) { + out.ensureWritable(4); + out.writerIndex(PacketService.PACKET_HEAD_LENGTH); + ByteBufUtils.writeLong(out, tunnelProtocol.getSid()); + out.writeBytes(tunnelProtocol.getByteBuf()); + + int length = out.writerIndex(); + int packetLength = length - PacketService.PACKET_HEAD_LENGTH; + out.writerIndex(0); + out.writeInt(packetLength); + out.writerIndex(length); + } + +} diff --git a/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelServerRouteHandler.java b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelServerRouteHandler.java new file mode 100644 index 00000000..38b8dc43 --- /dev/null +++ b/net/src/main/java/com/zfoo/net/core/proxy/handler/TunnelServerRouteHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.handler; + +import com.zfoo.net.core.proxy.TunnelServer; +import com.zfoo.net.handler.ServerRouteHandler; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; + +/** + * @author godotg + */ +@ChannelHandler.Sharable +public class TunnelServerRouteHandler extends ServerRouteHandler { + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + super.channelInactive(ctx); + TunnelServer.tunnels.remove(ctx.channel()); + } +} diff --git a/net/src/test/java/com/zfoo/net/core/proxy/client/ReverseProxyClientController.java b/net/src/test/java/com/zfoo/net/core/proxy/client/ReverseProxyClientController.java new file mode 100644 index 00000000..259813f1 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/core/proxy/client/ReverseProxyClientController.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.client; + +import com.zfoo.net.anno.PacketReceiver; +import com.zfoo.net.packet.proxy.ProxyHelloResponse; +import com.zfoo.net.packet.tcp.TcpHelloResponse; +import com.zfoo.net.session.Session; +import com.zfoo.protocol.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * @author jaysunxiao + */ +@Component +public class ReverseProxyClientController { + + + private static final Logger logger = LoggerFactory.getLogger(ReverseProxyClientController.class); + + @PacketReceiver + public void atProxyHelloResponse(Session session, ProxyHelloResponse response) { + logger.info("proxy client receive [packet:{}] from server", JsonUtils.object2String(response)); + } + +} diff --git a/net/src/test/java/com/zfoo/net/core/proxy/client/ReverseProxyClientTest.java b/net/src/test/java/com/zfoo/net/core/proxy/client/ReverseProxyClientTest.java new file mode 100644 index 00000000..eaf8e916 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/core/proxy/client/ReverseProxyClientTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.client; + +import com.zfoo.net.NetContext; +import com.zfoo.net.core.HostAndPort; +import com.zfoo.net.core.tcp.TcpClient; +import com.zfoo.net.packet.tcp.TcpHelloRequest; +import com.zfoo.net.packet.tcp.TcpHelloResponse; +import com.zfoo.protocol.util.JsonUtils; +import com.zfoo.protocol.util.ThreadUtils; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.function.Consumer; + +/** + * @author jaysunxiao + */ +@Ignore +public class ReverseProxyClientTest { + + private static final Logger logger = LoggerFactory.getLogger(ReverseProxyClientTest.class); + + @Test + public void startClient() throws Exception { + var context = new ClassPathXmlApplicationContext("config.xml"); + + var client = new TcpClient(HostAndPort.valueOf("127.0.0.1:9000")); + var session = client.start(); + + var request = TcpHelloRequest.valueOf("Hello, this is the tcp client!"); + var response = NetContext.getRouter().syncAsk(session, request, TcpHelloResponse.class, null).packet(); + logger.info("sync client receive [packet:{}] from server", JsonUtils.object2String(response)); + + ThreadUtils.sleep(Long.MAX_VALUE); + } + +} diff --git a/net/src/test/java/com/zfoo/net/core/proxy/server/ReverseProxyServerController.java b/net/src/test/java/com/zfoo/net/core/proxy/server/ReverseProxyServerController.java new file mode 100644 index 00000000..73929605 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/core/proxy/server/ReverseProxyServerController.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * 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.zfoo.net.core.proxy.server; + +import com.zfoo.net.NetContext; +import com.zfoo.net.anno.PacketReceiver; +import com.zfoo.net.packet.proxy.ProxyHelloRequest; +import com.zfoo.net.packet.tcp.TcpHelloRequest; +import com.zfoo.net.packet.tcp.TcpHelloResponse; +import com.zfoo.net.session.Session; +import com.zfoo.protocol.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * @author jaysunxiao + */ +@Component +public class ReverseProxyServerController { + + private static final Logger logger = LoggerFactory.getLogger(ReverseProxyServerController.class); + + @PacketReceiver + public void atProxyHelloRequest(Session session, ProxyHelloRequest request) { + logger.info("receive [packet:{}] from client", JsonUtils.object2String(request)); + + var response = new TcpHelloResponse(); + response.setMessage("Hello, this is the proxy server! -> " + request.getMessage()); + + NetContext.getRouter().send(session, response); + } + +} diff --git a/net/src/test/java/com/zfoo/net/core/proxy/server/ReverseProxyServerTest.java b/net/src/test/java/com/zfoo/net/core/proxy/server/ReverseProxyServerTest.java new file mode 100644 index 00000000..1ab7c422 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/core/proxy/server/ReverseProxyServerTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.server; + +import com.zfoo.net.core.HostAndPort; +import com.zfoo.net.core.proxy.TunnelServer; +import com.zfoo.net.core.tcp.TcpServer; +import com.zfoo.protocol.util.ThreadUtils; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * @author jaysunxiao + */ +@Ignore +public class ReverseProxyServerTest { + + /** + * ReverseProxyServerTest reverse proxy TargetServerTest + */ + @Test + public void startServer() { + var context = new ClassPathXmlApplicationContext("config.xml"); + + var server = new TcpServer(HostAndPort.valueOf("0.0.0.0:9000")); + server.start(); + + var reverseProxyServer = new TunnelServer(HostAndPort.valueOf("0.0.0.0:9001")); + reverseProxyServer.start(); + + ThreadUtils.sleep(Long.MAX_VALUE); + } + +} diff --git a/net/src/test/java/com/zfoo/net/core/proxy/server/TargetServerTest.java b/net/src/test/java/com/zfoo/net/core/proxy/server/TargetServerTest.java new file mode 100644 index 00000000..9ab92bf1 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/core/proxy/server/TargetServerTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * 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.zfoo.net.core.proxy.server; + +import com.zfoo.net.core.HostAndPort; +import com.zfoo.net.core.tcp.TcpClient; +import com.zfoo.net.core.tcp.TcpServer; +import com.zfoo.protocol.util.ThreadUtils; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * @author jaysunxiao + */ +@Ignore +public class TargetServerTest { + + /** + * 单机服务器教程,启动成功过后在com.zfoo.net.core.tcp.client.TcpClientTest中运行startClientTest + *

+ * startClientTest连接服务器成功过后,会不断的发消息给服务器 + */ + @Test + public void startServer() { + var context = new ClassPathXmlApplicationContext("config.xml"); + + var reverseProxyClient = new TcpClient(HostAndPort.valueOf("127.0.0.1:9001")); + var session = reverseProxyClient.start(); + + ThreadUtils.sleep(Long.MAX_VALUE); + } + +} diff --git a/net/src/test/java/com/zfoo/net/packet/proxy/ProxyHelloRequest.java b/net/src/test/java/com/zfoo/net/packet/proxy/ProxyHelloRequest.java new file mode 100644 index 00000000..1d91a3d2 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/packet/proxy/ProxyHelloRequest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * 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.zfoo.net.packet.proxy; + +/** + * @author jaysunxiao + */ +public class ProxyHelloRequest { + private String message; + + public static ProxyHelloRequest valueOf(String message) { + var request = new ProxyHelloRequest(); + request.message = message; + return request; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/net/src/test/java/com/zfoo/net/packet/proxy/ProxyHelloResponse.java b/net/src/test/java/com/zfoo/net/packet/proxy/ProxyHelloResponse.java new file mode 100644 index 00000000..884b8e23 --- /dev/null +++ b/net/src/test/java/com/zfoo/net/packet/proxy/ProxyHelloResponse.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * 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.zfoo.net.packet.proxy; + +/** + * @author jaysunxiao + */ +public class ProxyHelloResponse { + + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/net/src/test/resources/protocol.xml b/net/src/test/resources/protocol.xml index 927d8d07..b96c9fa2 100644 --- a/net/src/test/resources/protocol.xml +++ b/net/src/test/resources/protocol.xml @@ -63,6 +63,9 @@ + + +