/**
* Copyright 2012 Jason Sorensen (sorensenj@smert.net)
*
* 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 net.smert.frameworkgl;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.util.function.Supplier;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class Network {
private boolean debug;
private boolean keepAlive;
private boolean serverRunning;
private boolean tcpNoDelay;
private int backlog;
private int serverPort;
private Bootstrap client;
private EventLoopGroup clientWorkerGroup;
private EventLoopGroup serverAcceptGroup;
private EventLoopGroup serverWorkerGroup;
private LogLevel logLevel;
private ServerBootstrap server;
public Network() {
keepAlive = true;
tcpNoDelay = true;
backlog = 128;
serverPort = 0;
logLevel = LogLevel.INFO;
}
private void createClient(String host, int port, Supplier<ChannelHandler> channelHandlerSupplier) {
// Create event loops
clientWorkerGroup = new NioEventLoopGroup();
// Create channel initializer
ChannelInitializer<SocketChannel> channelInit = new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (debug) {
p.addLast(new LoggingHandler(logLevel));
}
p.addLast(channelHandlerSupplier.get());
}
};
// Bootstrap the client
client = new Bootstrap();
if (debug) {
client.handler(new LoggingHandler(logLevel));
}
client.group(clientWorkerGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, keepAlive)
.option(ChannelOption.TCP_NODELAY, tcpNoDelay)
.handler(channelInit);
// Connect to the host and port
client.connect(host, port);
}
private void createServer(int port, Supplier<ChannelHandler> channelHandlerSupplier) {
// Are we already running?
if (serverRunning) {
return;
}
serverPort = port;
// Create event loops
serverAcceptGroup = new NioEventLoopGroup(1);
serverWorkerGroup = new NioEventLoopGroup();
// Create channel initializer
ChannelInitializer<SocketChannel> channelInit = new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (debug) {
p.addLast(new LoggingHandler(logLevel));
}
p.addLast(channelHandlerSupplier.get());
}
};
// Bootstrap the server
server = new ServerBootstrap();
if (debug) {
server.handler(new LoggingHandler(logLevel));
}
server.group(serverAcceptGroup, serverWorkerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, backlog)
.childHandler(channelInit)
.childOption(ChannelOption.SO_KEEPALIVE, keepAlive)
.childOption(ChannelOption.TCP_NODELAY, tcpNoDelay);
// Start listening on the port
server.bind(port);
// The server is now running
serverRunning = true;
}
public void destroy() {
if (clientWorkerGroup != null) {
clientWorkerGroup.shutdownGracefully();
clientWorkerGroup = null;
}
client = null;
if (serverAcceptGroup != null) {
serverAcceptGroup.shutdownGracefully();
serverAcceptGroup = null;
}
if (serverWorkerGroup != null) {
serverWorkerGroup.shutdownGracefully();
serverWorkerGroup = null;
}
server = null;
serverRunning = false;
}
public int getBacklog() {
return backlog;
}
public void setBacklog(int backlog) {
this.backlog = backlog;
}
public int getServerPort() {
return serverPort;
}
public boolean isDebug() {
return debug;
}
public LogLevel getLogLevel() {
return logLevel;
}
public void setLogLevelDebug() {
this.logLevel = LogLevel.DEBUG;
}
public void setLogLevelError() {
this.logLevel = LogLevel.ERROR;
}
public void setLogLevelInfo() {
this.logLevel = LogLevel.INFO;
}
public void setLogLevelTrace() {
this.logLevel = LogLevel.TRACE;
}
public void setLogLevelWarn() {
this.logLevel = LogLevel.WARN;
}
public ServerBootstrap getServer() {
return server;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public boolean isKeepAlive() {
return keepAlive;
}
public void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
}
public boolean isTcpNoDelay() {
return tcpNoDelay;
}
public void setTcpNoDelay(boolean tcpNoDelay) {
this.tcpNoDelay = tcpNoDelay;
}
public void startClient(String host, int port, ChannelHandler sharedChannelHandler) {
Supplier<ChannelHandler> channelHandlerSupplier = () -> {
return sharedChannelHandler;
};
createClient(host, port, channelHandlerSupplier);
}
public void startClient(String host, int port, Supplier<ChannelHandler> channelHandlerSupplier) {
createClient(host, port, channelHandlerSupplier);
}
public void startServer(int port, ChannelHandler sharedChannelHandler) {
Supplier<ChannelHandler> channelHandlerSupplier = () -> {
return sharedChannelHandler;
};
createServer(port, channelHandlerSupplier);
}
public void startServer(int port, Supplier<ChannelHandler> channelHandlerSupplier) {
createServer(port, channelHandlerSupplier);
}
}