Archived
0
This commit is contained in:
2017-06-09 09:33:15 +03:00
parent d51d7f1d86
commit e2c2f6be8a
7 changed files with 379 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-21
*/
package asys.multiserver.netty;
import asys.multiserver.netty.codec.MessagePkbEncoder;
import asys.multiserver.netty.codec.MessagePkgDecoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
public class Server {
public static final long SECRET_CODE = 15487445812L;
private String host;
private short port;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
public Server(String host, short port) {
this.host = host;
this.port = port;
}
public void start() throws InterruptedException {
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = prepare_ServerBootstrap();
// Start the server. // Wait until the server socket is closed.
bootstrap.bind(host, port).sync().channel().closeFuture().sync();
}
private ServerBootstrap prepare_ServerBootstrap() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
// .option(ChannelOption.SO_BACKLOG, 100) //TODO debug
// .handler(new LoggingHandler(LogLevel.INFO)) //TODO debug
.childHandler(prepare_ChannelInitializer())
.childOption(ChannelOption.SO_KEEPALIVE, true);
return bootstrap;
}
private ChannelInitializer prepare_ChannelInitializer() {
return new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
// pipeline.addLast("idleStateHandler",new IdleStateHandler(0,0,1)); // add with name
// pipeline.addLast(new TimeStampEncoder()); // add without name, name auto generated
// pipeline.addLast(new TimeStampDecoder()); // add without name, name auto generated
pipeline.addLast(
// new IdleStateHandler(0,0,1),
new MessagePkbEncoder(),
new MessagePkgDecoder(),
new ServerHandler()
);
// ===========================================================
// 1. define a separate thread pool to execute handlers with
// slow business logic. e.g database operation
// ===========================================================
// final EventExecutorGroup evtGroup = new DefaultEventExecutorGroup(1500); //thread pool of 1500
//===========================================================
// 2. run handler with slow business logic
// in separate thread from I/O thread
//===========================================================
// pipeline.addLast(evtGroup, "serverHandler", new ServerHandler());
// pipeline.addLast("serverHandler", serverHandler);
}
};
}
public void stop() throws InterruptedException {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
public void send(MessagePkg obj) {
ServerHandler.Send(obj);
}
}

View File

@@ -0,0 +1,77 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-21
*/
package asys.multiserver.netty;
import asys.api.ASysUtils;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.concurrent.FutureListener;
//import io.netty.channel.group.ChannelGroup;
//import io.netty.channel.group.DefaultChannelGroup;
//import io.netty.handler.timeout.IdleState;
//import io.netty.handler.timeout.IdleStateEvent;
//import io.netty.util.concurrent.GlobalEventExecutor;
public class ServerHandler extends ChannelInboundHandlerAdapter {
// private ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private static Channel channel;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// ASysUtils.Log("Server: channel Active");
// channels.add(ctx.channel());
// if (channel != null) {
// ctx.close();
// } else {
// channel = ctx.channel();
// }
if (channel != null) {
ctx.channel().close();
} else {
channel = ctx.channel();
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// ASysUtils.Log("Server: channel Inactive");
// channels.remove(ctx.channel());
// channel.close();
// channel = null;
if (channel != null && ctx.channel().equals(channel)) {
channel = null;
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
}
// Here is how we Send out heart beat for idle to long
// @Override
// public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
// if (evt instanceof IdleStateEvent) {
// IdleStateEvent event = (IdleStateEvent) evt;
// if (event.state() == IdleState.ALL_IDLE && checkChannel()) { // idle for no read and write
// MessagePkg pkg = new MessagePkg("idle ping...");
// this.channel.writeAndFlush(pkg).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
// }
// }
// }
private static boolean checkChannel() {
return channel != null && channel.isOpen();
}
public static void Send(MessagePkg obj) {
// channels = channels.writeAndFlush(obj).group();
// if (channel == null) return;
if (checkChannel())
channel.writeAndFlush(obj).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
}

View File

@@ -0,0 +1,44 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-24
*/
package asys.multiserver.netty.mcnettyremix;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
public class McNettyServerRemix {
public static void main(String[] args) {
ServerBootstrap serverBootstrap = new ServerBootstrap();
Class <? extends ServerSocketChannel> oclass = NioServerSocketChannel.class;
serverBootstrap.channel(oclass); //TODO если никак не оправдается - вернуть в "нормальный" вид
serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) throws Exception {
channel.config().setOption(ChannelOption.TCP_NODELAY, true); //TODO что такое TCP_NODELAY?
channel.pipeline()
.addLast("timeout", new ReadTimeoutHandler(30))
// .addLast("legacy_query", new PingResponseHandler(NetworkSystem.this))
.addLast("splitter", new MessageDeserializer2())
.addLast("decoder", new MessageDeserializer(EnumPacketDirection.SERVERBOUND))
.addLast("prepender", new MessageSerializer2())
.addLast("encoder", new MessageSerializer(EnumPacketDirection.CLIENTBOUND));
NetworkManager networkmanager = new NetworkManager(EnumPacketDirection.SERVERBOUND);
channel.pipeline()
.addLast("packet_handler", networkmanager); //TODO обработчик пакетов???
}
});
serverBootstrap.group(new NioEventLoopGroup(
0,
(new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build() //TODO другими словами, делается некая фабрика потоков, в которую передается Runnable
));
serverBootstrap.localAddress(9090).bind().syncUninterruptibly(); //TODO как переводится syncUninterruptibly?
}
}

View File

@@ -0,0 +1,38 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-24
*/
package asys.multiserver.netty.mcnettyremix;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class NetworkManager extends SimpleChannelInboundHandler<Packet> {
private Channel channel;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.channel = ctx.channel();
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Packet packet) throws Exception {
if (this.channel.isOpen()) {
packet.processPacket(packetListener);
}
}
public void sendPacket(Packet packetIn) {
if (isChannelOpen()) {
}
}
public boolean isChannelOpen()
{
return this.channel != null && this.channel.isOpen();
}
}

View File

@@ -0,0 +1,32 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-21
*/
package asys.multiserver.netty;
import asys.multiserver.netty.client.Client;
public class TestServer {
public static void main(String[] args) throws InterruptedException {
// final Server server = new Server("127.0.0.1", (short)6251);
// new Thread(() -> {
// try {
// server.start();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }).start();
//
Client client = new Client("127.0.0.1", (short)6251);
client.connect();
// LoopBackTimeStamp obj = new LoopBackTimeStamp();
// obj.setSendTimeStamp(0L);
//// client.Send(obj);
// Thread.sleep(2000L);
//// obj.setSendTimeStamp(System.nanoTime());
//// client.Send(obj);
// server.Send(obj);
//// client.disconnect();
//// server.stop();
}
}

View File

@@ -0,0 +1,72 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-21
*/
package asys.multiserver.netty.client;
import asys.multiserver.netty.MessagePkg;
import asys.multiserver.netty.codec.MessagePkbEncoder;
import asys.multiserver.netty.codec.MessagePkgDecoder;
//import asys.multiserver.netty.codec.TimeStampDecoder;
//import asys.multiserver.netty.codec.TimeStampEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class Client {
private String host;
private short port;
private EventLoopGroup group;
private Channel channel;
public Client(String host, short port) {
this.host = host;
this.port = port;
}
public void connect() throws InterruptedException {
group = new NioEventLoopGroup();
Bootstrap bootstrap = prepare_Bootstrap();
channel = bootstrap.connect(host, port).sync().channel();
}
private Bootstrap prepare_Bootstrap() {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
// .option(ChannelOption.TCP_NODELAY, true) //TODO debug
.handler(prepare_ChannelInitializer());
return bootstrap;
}
private ChannelInitializer prepare_ChannelInitializer() {
return new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(
// new TimeStampEncoder(),
// new TimeStampDecoder(),
new MessagePkbEncoder(),
new MessagePkgDecoder(),
new ClientHandler()
);
}
};
}
public void disconnect() {
group.shutdownGracefully();
}
public void send(MessagePkg obj) {
channel = channel.writeAndFlush(obj).channel();
}
}

View File

@@ -0,0 +1,25 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-08-21
*/
package asys.multiserver.netty.client;
import asys.api.ASysUtils;
//import asys.multiserver.netty.LoopBackTimeStamp;
import asys.multiserver.netty.MessagePkg;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class ClientHandler extends SimpleChannelInboundHandler<MessagePkg> {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, MessagePkg messagePkg) throws Exception {
ASysUtils.Log("Incomming message: %s", messagePkg.getMessage());
}
}