mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-09-04 06:20:19 +00:00
feat[udp]: 支持udp服务器
This commit is contained in:
@@ -38,16 +38,16 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public abstract class AbstractClient implements IClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractClient.class);
|
||||
protected static final Logger logger = LoggerFactory.getLogger(AbstractClient.class);
|
||||
|
||||
private static final EventLoopGroup nioEventLoopGroup = Epoll.isAvailable()
|
||||
protected static final EventLoopGroup nioEventLoopGroup = Epoll.isAvailable()
|
||||
? new EpollEventLoopGroup(Runtime.getRuntime().availableProcessors() + 1, new DefaultThreadFactory("netty-client", true))
|
||||
: new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() + 1, new DefaultThreadFactory("netty-client", true));
|
||||
|
||||
private String hostAddress;
|
||||
private int port;
|
||||
protected String hostAddress;
|
||||
protected int port;
|
||||
|
||||
private Bootstrap bootstrap;
|
||||
protected Bootstrap bootstrap;
|
||||
|
||||
public AbstractClient(HostAndPort host) {
|
||||
this.hostAddress = host.getHost();
|
||||
|
||||
@@ -37,21 +37,21 @@ public abstract class AbstractServer implements IServer {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractServer.class);
|
||||
|
||||
// 所有的服务器都可以在这个列表中取到
|
||||
private static final List<AbstractServer> allServers = new ArrayList<>(1);
|
||||
protected static final List<AbstractServer> allServers = new ArrayList<>(1);
|
||||
|
||||
private String hostAddress;
|
||||
private int port;
|
||||
protected String hostAddress;
|
||||
protected int port;
|
||||
|
||||
|
||||
// 配置服务端nio线程组,服务端接受客户端连接
|
||||
private EventLoopGroup bossGroup;
|
||||
|
||||
// SocketChannel的网络读写
|
||||
private EventLoopGroup workerGroup;
|
||||
protected EventLoopGroup workerGroup;
|
||||
|
||||
private ChannelFuture channelFuture;
|
||||
protected ChannelFuture channelFuture;
|
||||
|
||||
private Channel channel;
|
||||
protected Channel channel;
|
||||
|
||||
public AbstractServer(HostAndPort host) {
|
||||
this.hostAddress = host.getHost();
|
||||
@@ -79,7 +79,7 @@ public abstract class AbstractServer implements IServer {
|
||||
bootstrap.group(bossGroup, workerGroup)
|
||||
.channel(Epoll.isAvailable() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
|
||||
.option(ChannelOption.SO_REUSEADDR, true)
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.childOption(ChannelOption.TCP_NODELAY, true)
|
||||
.childHandler(channelChannelInitializer);
|
||||
// 绑定端口,同步等待成功
|
||||
// channelFuture = bootstrap.bind(hostAddress, port).sync();
|
||||
@@ -122,6 +122,9 @@ public abstract class AbstractServer implements IServer {
|
||||
}
|
||||
|
||||
public synchronized static void shutdownEventLoopGracefully(EventExecutorGroup executor) {
|
||||
if (executor == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (executor.isShutdown() || executor.isTerminated()) {
|
||||
executor.shutdownGracefully();
|
||||
|
||||
@@ -42,15 +42,15 @@ public class GatewayServer extends AbstractServer {
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<SocketChannel> channelChannelInitializer() {
|
||||
return new GatewayChannelHandler(packetFilter);
|
||||
return new ChannelHandlerInitializer(packetFilter);
|
||||
}
|
||||
|
||||
|
||||
private static class GatewayChannelHandler extends ChannelInitializer<SocketChannel> {
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
private BiFunction<Session, IPacket, Boolean> packetFilter;
|
||||
|
||||
public GatewayChannelHandler(BiFunction<Session, IPacket, Boolean> packetFilter) {
|
||||
public ChannelHandlerInitializer(BiFunction<Session, IPacket, Boolean> packetFilter) {
|
||||
this.packetFilter = packetFilter;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,15 +46,15 @@ public class WebsocketGatewayServer extends AbstractServer {
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<SocketChannel> channelChannelInitializer() {
|
||||
return new GatewayChannelHandler(packetFilter);
|
||||
return new ChannelHandlerInitializer(packetFilter);
|
||||
}
|
||||
|
||||
|
||||
private static class GatewayChannelHandler extends ChannelInitializer<SocketChannel> {
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
private BiFunction<Session, IPacket, Boolean> packetFilter;
|
||||
|
||||
public GatewayChannelHandler(BiFunction<Session, IPacket, Boolean> packetFilter) {
|
||||
public ChannelHandlerInitializer(BiFunction<Session, IPacket, Boolean> packetFilter) {
|
||||
this.packetFilter = packetFilter;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,16 +61,16 @@ public class WebsocketSslGatewayServer extends AbstractServer {
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<SocketChannel> channelChannelInitializer() {
|
||||
return new GatewayChannelHandler(sslContext, packetFilter);
|
||||
return new ChannelHandlerInitializer(sslContext, packetFilter);
|
||||
}
|
||||
|
||||
|
||||
private static class GatewayChannelHandler extends ChannelInitializer<SocketChannel> {
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
private SslContext sslContext;
|
||||
private BiFunction<Session, IPacket, Boolean> packetFilter;
|
||||
|
||||
public GatewayChannelHandler(SslContext sslContext, BiFunction<Session, IPacket, Boolean> packetFilter) {
|
||||
public ChannelHandlerInitializer(SslContext sslContext, BiFunction<Session, IPacket, Boolean> packetFilter) {
|
||||
this.sslContext = sslContext;
|
||||
this.packetFilter = packetFilter;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,11 @@ public class TcpClient extends AbstractClient {
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<? extends Channel> channelChannelInitializer() {
|
||||
return new TcpChannelInitHandler();
|
||||
return new ChannelHandlerInitializer();
|
||||
}
|
||||
|
||||
|
||||
private static class TcpChannelInitHandler extends ChannelInitializer<SocketChannel> {
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel channel) {
|
||||
channel.pipeline().addLast(new IdleStateHandler(0, 0, 60));
|
||||
|
||||
@@ -34,11 +34,11 @@ public class TcpServer extends AbstractServer {
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<SocketChannel> channelChannelInitializer() {
|
||||
return new TcpChannelHandler();
|
||||
return new ChannelHandlerInitializer();
|
||||
}
|
||||
|
||||
|
||||
private static class TcpChannelHandler extends ChannelInitializer<SocketChannel> {
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel channel) {
|
||||
channel.pipeline().addLast(new IdleStateHandler(0, 0, 180));
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.udp;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.core.AbstractClient;
|
||||
import com.zfoo.net.handler.BaseDispatcherHandler;
|
||||
import com.zfoo.net.handler.ClientDispatcherHandler;
|
||||
import com.zfoo.net.handler.codec.udp.UdpCodecHandler;
|
||||
import com.zfoo.net.session.model.Session;
|
||||
import com.zfoo.protocol.exception.ExceptionUtils;
|
||||
import com.zfoo.util.net.HostAndPort;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.epoll.Epoll;
|
||||
import io.netty.channel.epoll.EpollDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UdpClient extends AbstractClient {
|
||||
|
||||
public UdpClient(HostAndPort host) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Session start() {
|
||||
try {
|
||||
this.bootstrap = new Bootstrap();
|
||||
this.bootstrap.group(nioEventLoopGroup)
|
||||
.channel(Epoll.isAvailable() ? EpollDatagramChannel.class : NioDatagramChannel.class)
|
||||
.option(ChannelOption.SO_BROADCAST, true)
|
||||
.handler(new ChannelHandlerInitializer());
|
||||
|
||||
// bind(0)随机选择一个端口
|
||||
var channelFuture = bootstrap.bind(0).sync();
|
||||
channelFuture.syncUninterruptibly();
|
||||
|
||||
if (channelFuture.isSuccess()) {
|
||||
if (channelFuture.channel().isActive()) {
|
||||
var channel = channelFuture.channel();
|
||||
var session = BaseDispatcherHandler.initChannel(channel);
|
||||
NetContext.getSessionManager().addClientSession(session);
|
||||
logger.info("UdpClient started at [{}]", channel.localAddress());
|
||||
return session;
|
||||
}
|
||||
} else if (channelFuture.cause() != null) {
|
||||
logger.error(ExceptionUtils.getMessage(channelFuture.cause()));
|
||||
} else {
|
||||
logger.error("启动客户端[client:{}]未知错误", this);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(ExceptionUtils.getMessage(e));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<Channel> channelChannelInitializer() {
|
||||
return new ChannelHandlerInitializer();
|
||||
}
|
||||
|
||||
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<Channel> {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) {
|
||||
channel.pipeline().addLast(new UdpCodecHandler());
|
||||
channel.pipeline().addLast(new ClientDispatcherHandler());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.udp;
|
||||
|
||||
import com.zfoo.net.core.AbstractServer;
|
||||
import com.zfoo.net.handler.ServerDispatcherHandler;
|
||||
import com.zfoo.net.handler.codec.udp.UdpCodecHandler;
|
||||
import com.zfoo.util.net.HostAndPort;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.epoll.Epoll;
|
||||
import io.netty.channel.epoll.EpollDatagramChannel;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UdpServer extends AbstractServer {
|
||||
|
||||
public UdpServer(HostAndPort host) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
var cpuNum = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
// 配置服务端nio线程组
|
||||
workerGroup = Epoll.isAvailable()
|
||||
? new EpollEventLoopGroup(cpuNum * 2, new DefaultThreadFactory("netty-worker", true))
|
||||
: new NioEventLoopGroup(cpuNum * 2, new DefaultThreadFactory("netty-worker", true));
|
||||
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(workerGroup)
|
||||
.channel(Epoll.isAvailable() ? EpollDatagramChannel.class : NioDatagramChannel.class)
|
||||
.option(ChannelOption.SO_BROADCAST, true)
|
||||
.handler(channelChannelInitializer());
|
||||
|
||||
// 异步
|
||||
channelFuture = bootstrap.bind(hostAddress, port);
|
||||
channelFuture.syncUninterruptibly();
|
||||
channel = channelFuture.channel();
|
||||
|
||||
allServers.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<Channel> channelChannelInitializer() {
|
||||
return new ChannelHandlerInitializer();
|
||||
}
|
||||
|
||||
|
||||
private static class ChannelHandlerInitializer extends ChannelInitializer<Channel> {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) {
|
||||
channel.pipeline().addLast(new UdpCodecHandler());
|
||||
channel.pipeline().addLast(new ServerDispatcherHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,11 +37,11 @@ public class WebsocketServer extends AbstractServer {
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<SocketChannel> channelChannelInitializer() {
|
||||
return new WebSocketServerInitializer();
|
||||
return new ChannelHandlerInitializer();
|
||||
}
|
||||
|
||||
|
||||
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
public static class ChannelHandlerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel channel) {
|
||||
@@ -59,7 +59,6 @@ public class WebsocketServer extends AbstractServer {
|
||||
pipeline.addLast(new WebSocketCodecHandler());
|
||||
pipeline.addLast(new ServerDispatcherHandler());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.zfoo.net.dispatcher.model.vo.IPacketReceiver;
|
||||
import com.zfoo.net.dispatcher.model.vo.PacketReceiverDefinition;
|
||||
import com.zfoo.net.packet.model.GatewayPacketAttachment;
|
||||
import com.zfoo.net.packet.model.IPacketAttachment;
|
||||
import com.zfoo.net.packet.model.UdpPacketAttachment;
|
||||
import com.zfoo.net.packet.service.PacketService;
|
||||
import com.zfoo.net.session.model.Session;
|
||||
import com.zfoo.protocol.IPacket;
|
||||
@@ -109,7 +110,7 @@ public abstract class PacketBus {
|
||||
// 如果以Ask结尾的请求,那么attachment不能为GatewayAttachment
|
||||
if (attachmentClazz != null) {
|
||||
if (packetName.endsWith(PacketService.NET_REQUEST_SUFFIX)) {
|
||||
AssertionUtils.isTrue(attachmentClazz.equals(GatewayPacketAttachment.class)
|
||||
AssertionUtils.isTrue(attachmentClazz.equals(GatewayPacketAttachment.class) || attachmentClazz.equals(UdpPacketAttachment.class)
|
||||
, "[class:{}] [method:{}] [packet:{}] must use [attachment:{}]!", bean.getClass().getName(), methodName, packetName, GatewayPacketAttachment.class.getCanonicalName());
|
||||
} else if (packetName.endsWith(PacketService.NET_ASK_SUFFIX)) {
|
||||
AssertionUtils.isTrue(!attachmentClazz.equals(GatewayPacketAttachment.class)
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.handler.codec.udp;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.packet.model.DecodedPacketInfo;
|
||||
import com.zfoo.net.packet.model.EncodedPacketInfo;
|
||||
import com.zfoo.net.packet.model.UdpPacketAttachment;
|
||||
import com.zfoo.net.packet.service.PacketService;
|
||||
import com.zfoo.net.util.SessionUtils;
|
||||
import com.zfoo.protocol.util.JsonUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import io.netty.handler.codec.MessageToMessageCodec;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UdpCodecHandler extends MessageToMessageCodec<DatagramPacket, EncodedPacketInfo> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UdpCodecHandler.class);
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket, List<Object> list) {
|
||||
ByteBuf in = datagramPacket.content();
|
||||
|
||||
// 不够读一个int
|
||||
if (in.readableBytes() <= PacketService.PACKET_HEAD_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
in.markReaderIndex();
|
||||
var length = in.readInt();
|
||||
|
||||
// 如果长度非法,则抛出异常断开连接
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException(StringUtils.format("[session:{}]的包头长度[length:{}]非法"
|
||||
, SessionUtils.sessionInfo(channelHandlerContext), length));
|
||||
}
|
||||
|
||||
// ByteBuf里的数据太小
|
||||
if (in.readableBytes() < length) {
|
||||
in.resetReaderIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuf tmpByteBuf = null;
|
||||
try {
|
||||
tmpByteBuf = in.readRetainedSlice(length);
|
||||
DecodedPacketInfo packetInfo = NetContext.getPacketService().read(tmpByteBuf);
|
||||
var sender = datagramPacket.sender();
|
||||
packetInfo.setPacketAttachment(UdpPacketAttachment.valueOf(sender.getHostString(), sender.getPort()));
|
||||
list.add(packetInfo);
|
||||
} catch (Exception e) {
|
||||
logger.error("exception异常", e);
|
||||
throw e;
|
||||
} catch (Throwable t) {
|
||||
logger.error("throwable错误", t);
|
||||
throw t;
|
||||
} finally {
|
||||
ReferenceCountUtil.release(tmpByteBuf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext channelHandlerContext, EncodedPacketInfo out, List<Object> list) {
|
||||
try {
|
||||
ByteBuf byteBuf = Unpooled.directBuffer();
|
||||
byteBuf.clear();
|
||||
|
||||
var udpPacketAttachment = (UdpPacketAttachment) out.getPacketAttachment();
|
||||
|
||||
NetContext.getPacketService().write(byteBuf, out.getPacket(), out.getPacketAttachment());
|
||||
list.add(new DatagramPacket(byteBuf, new InetSocketAddress(udpPacketAttachment.getHost(), udpPacketAttachment.getPort())));
|
||||
} catch (Exception e) {
|
||||
logger.error("[{}]编码exception异常", JsonUtils.object2String(out), e);
|
||||
throw e;
|
||||
} catch (Throwable t) {
|
||||
logger.error("[{}]编码throwable错误", JsonUtils.object2String(out), t);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ package com.zfoo.net.packet.model;
|
||||
*/
|
||||
public class NoAnswerAttachment implements IPacketAttachment {
|
||||
|
||||
public static final transient short PROTOCOL_ID = 2;
|
||||
public static final transient short PROTOCOL_ID = 3;
|
||||
|
||||
/**
|
||||
* 用来在TaskManage中计算一致性hash的参数
|
||||
|
||||
@@ -37,10 +37,16 @@ public enum PacketAttachmentType {
|
||||
*/
|
||||
GATEWAY_PACKET((byte) 2, GatewayPacketAttachment.class),
|
||||
|
||||
/**
|
||||
* udp消息的附加包
|
||||
*/
|
||||
UDP_PACKET((byte) 3, NoAnswerAttachment.class),
|
||||
|
||||
/**
|
||||
* 无返回消息的附加包
|
||||
*/
|
||||
NO_ANSWER_PACKET((byte) 3, NoAnswerAttachment.class),
|
||||
NO_ANSWER_PACKET((byte) 4, NoAnswerAttachment.class),
|
||||
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -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.packet.model;
|
||||
|
||||
import com.zfoo.util.math.RandomUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UdpPacketAttachment implements IPacketAttachment {
|
||||
|
||||
public static final transient short PROTOCOL_ID = 2;
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public static UdpPacketAttachment valueOf(String host, int port) {
|
||||
var attachment = new UdpPacketAttachment();
|
||||
attachment.host = host;
|
||||
attachment.port = port;
|
||||
return attachment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketAttachmentType packetType() {
|
||||
return PacketAttachmentType.UDP_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executorConsistentHash() {
|
||||
return RandomUtils.randomInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short protocolId() {
|
||||
return PROTOCOL_ID;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.net.core.tcp.client.controller;
|
||||
package com.zfoo.net.core.tcp.client;
|
||||
|
||||
import com.zfoo.net.dispatcher.model.anno.PacketReceiver;
|
||||
import com.zfoo.net.packet.SM_Int;
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
@@ -11,7 +10,7 @@
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.net.core.tcp.server.controller;
|
||||
package com.zfoo.net.core.tcp.server;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.dispatcher.model.anno.PacketReceiver;
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.udp.client;
|
||||
|
||||
import com.zfoo.net.dispatcher.model.anno.PacketReceiver;
|
||||
import com.zfoo.net.packet.model.UdpPacketAttachment;
|
||||
import com.zfoo.net.packet.udp.UdpHelloResponse;
|
||||
import com.zfoo.net.session.model.Session;
|
||||
import com.zfoo.protocol.util.JsonUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Component
|
||||
public class UdpClientPacketController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UdpClientPacketController.class);
|
||||
|
||||
@PacketReceiver
|
||||
public void atUdpHelloResponse(Session session, UdpHelloResponse response, UdpPacketAttachment attachment) {
|
||||
logger.info("udp client receive [packet:{}] from server", JsonUtils.object2String(response));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.udp.client;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.core.udp.UdpClient;
|
||||
import com.zfoo.net.packet.model.UdpPacketAttachment;
|
||||
import com.zfoo.net.packet.udp.UdpHelloRequest;
|
||||
import com.zfoo.util.ThreadUtils;
|
||||
import com.zfoo.util.net.HostAndPort;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Ignore
|
||||
public class UdpClientTest {
|
||||
|
||||
@Test
|
||||
public void startClientTest() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("client_config.xml");
|
||||
var client = new UdpClient(HostAndPort.valueOf(NetContext.getConfigManager().getLocalConfig().getHostConfig().getAddressMap().get("server0")));
|
||||
|
||||
var session = client.start();
|
||||
|
||||
var request = new UdpHelloRequest();
|
||||
request.setMessage("Hello, this is the udp client!");
|
||||
|
||||
NetContext.getDispatcher().send(session, request, UdpPacketAttachment.valueOf("127.0.0.1", 9000));
|
||||
|
||||
ThreadUtils.sleep(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.udp.server;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.dispatcher.model.anno.PacketReceiver;
|
||||
import com.zfoo.net.packet.model.UdpPacketAttachment;
|
||||
import com.zfoo.net.packet.udp.UdpHelloRequest;
|
||||
import com.zfoo.net.packet.udp.UdpHelloResponse;
|
||||
import com.zfoo.net.session.model.Session;
|
||||
import com.zfoo.protocol.util.JsonUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Component
|
||||
public class UdpServerPacketController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UdpServerPacketController.class);
|
||||
|
||||
@PacketReceiver
|
||||
public void atUdpHelloRequest(Session session, UdpHelloRequest request, UdpPacketAttachment attachment) {
|
||||
logger.info("udp server receive [packet:{}] from client", JsonUtils.object2String(request));
|
||||
|
||||
var response = new UdpHelloResponse();
|
||||
response.setMessage("Hello, this is the udp server!");
|
||||
|
||||
NetContext.getDispatcher().send(session, response, attachment);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.udp.server;
|
||||
|
||||
import com.zfoo.net.NetContext;
|
||||
import com.zfoo.net.core.udp.UdpServer;
|
||||
import com.zfoo.util.ThreadUtils;
|
||||
import com.zfoo.util.net.HostAndPort;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
@Ignore
|
||||
public class UdpServerTest {
|
||||
|
||||
@Test
|
||||
public void startServerTest() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("server_config.xml");
|
||||
var server = new UdpServer(HostAndPort.valueOf(NetContext.getConfigManager().getLocalConfig().getHostConfig().getAddressMap().get("server0")));
|
||||
server.start();
|
||||
ThreadUtils.sleep(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.udp;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UdpHelloRequest implements IPacket {
|
||||
|
||||
public static final transient short PROTOCOL_ID = 1200;
|
||||
|
||||
private String message;
|
||||
|
||||
|
||||
@Override
|
||||
public short protocolId() {
|
||||
return PROTOCOL_ID;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.udp;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UdpHelloResponse implements IPacket {
|
||||
|
||||
public static final transient short PROTOCOL_ID = 1201;
|
||||
|
||||
private String message;
|
||||
|
||||
|
||||
@Override
|
||||
public short protocolId() {
|
||||
return PROTOCOL_ID;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,8 @@
|
||||
<module id="1" name="native" minId="0" maxId="100" version="99.99.999">
|
||||
<protocol id="0" location="com.zfoo.net.packet.model.SignalPacketAttachment"/>
|
||||
<protocol id="1" location="com.zfoo.net.packet.model.GatewayPacketAttachment"/>
|
||||
<protocol id="2" location="com.zfoo.net.packet.model.NoAnswerAttachment"/>
|
||||
<protocol id="2" location="com.zfoo.net.packet.model.UdpPacketAttachment"/>
|
||||
<protocol id="3" location="com.zfoo.net.packet.model.NoAnswerAttachment"/>
|
||||
|
||||
|
||||
<protocol id="20" location="com.zfoo.net.core.gateway.model.AuthUidToGatewayCheck"/>
|
||||
@@ -57,6 +58,9 @@
|
||||
<protocol id="1165" location="com.zfoo.net.packet.csharp.CM_CSharpRequest" enhance="false"/>
|
||||
<protocol id="1166" location="com.zfoo.net.packet.csharp.CSharpObjectA" enhance="false"/>
|
||||
<protocol id="1167" location="com.zfoo.net.packet.csharp.CSharpObjectB" enhance="false"/>
|
||||
|
||||
<protocol id="1200" location="com.zfoo.net.packet.udp.UdpHelloRequest"/>
|
||||
<protocol id="1201" location="com.zfoo.net.packet.udp.UdpHelloResponse"/>
|
||||
</module>
|
||||
|
||||
<module id="4" name="js" minId="2000" maxId="3000" version="1.0.0">
|
||||
|
||||
Reference in New Issue
Block a user