Simple TCP Server
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.filterchain.Filter;
import org.glassfish.grizzly.filterchain.FilterChainBuilder;
import org.glassfish.grizzly.filterchain.TransportFilter;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder;
import org.glassfish.grizzly.utils.DelayedExecutor;
import org.glassfish.grizzly.utils.IdleTimeoutFilter;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
public class SimpleTcpServer {
protected static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
protected volatile int backlog = 4096;
protected volatile int port = Short.MAX_VALUE;
protected volatile boolean closed = false;
protected volatile SocketAddress endpoint;
protected volatile TCPNIOTransport transport;
public TcpServer(int port) {
this.port = port;
this.endpoint = new InetSocketAddress(port);
}
public TcpServer(int port, int backlog) {
this.backlog = backlog;
this.port = port;
this.endpoint = new InetSocketAddress(port);
}
public void stop() {
this.closed = true;
Optional.ofNullable(this.transport).ifPresent(x -> {
x.unbindAll(); x.shutdown(); });
}
public void start(List<Filter> filters) throws RuntimeException {
this.closed = false;
TCPNIOTransportBuilder builder = TCPNIOTransportBuilder.newInstance();
builder.setServerConnectionBackLog(this.backlog);
builder.setReuseAddress(true);
builder.setKeepAlive(true);
builder.setTcpNoDelay(true);
builder.setLinger(0);
this.transport = builder.build();
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
final DelayedExecutor delayedExecutor = IdleTimeoutFilter.createDefaultIdleDelayedExecutor();
delayedExecutor.start();
filterChainBuilder.add(new IdleTimeoutFilter(delayedExecutor, 30, TimeUnit.SECONDS, Connection::closeSilently));
filterChainBuilder.add(new TransportFilter());
Optional.ofNullable(filters).ifPresent(filterChainBuilder::addAll);
this.transport.setProcessor(filterChainBuilder.build());
doBind();
}
protected void doBind() {
if (this.closed) {
return;
}
while (!this.closed) {
try {
this.transport.bind(this.endpoint);
this.transport.start();
return;
} catch (Exception ignored) {
}
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}
}
Simple TCP Client
import org.glassfish.grizzly.CloseListener;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.EmptyCompletionHandler;
import org.glassfish.grizzly.filterchain.Filter;
import org.glassfish.grizzly.filterchain.FilterChainBuilder;
import org.glassfish.grizzly.filterchain.TransportFilter;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder;
import org.glassfish.grizzly.utils.DelayedExecutor;
import org.glassfish.grizzly.utils.IdleTimeoutFilter;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class SimpleTcpClient {
protected volatile String addr = "127.0.0.1";
protected volatile int port = Short.MAX_VALUE;
protected volatile boolean closed = false;
protected volatile SocketAddress endpoint;
protected volatile TCPNIOTransport transport;
protected volatile Connection connection;
public TcpClient(String addr, int port) {
this.addr = addr;
this.port = port;
this.endpoint = new InetSocketAddress(addr, port);
}
public void stop() {
this.closed = true;
Optional.ofNullable(this.connection).ifPresent(Connection::closeSilently);
Optional.ofNullable(this.transport).ifPresent(x -> {
x.unbind(connection); x.shutdown(); });
}
public void start(List<Filter> filters) throws RuntimeException {
this.closed = false;
TCPNIOTransportBuilder builder = TCPNIOTransportBuilder.newInstance();
builder.setReuseAddress(true);
builder.setKeepAlive(true);
builder.setTcpNoDelay(true);
builder.setLinger(0);
this.transport = builder.build();
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
final DelayedExecutor delayedExecutor = IdleTimeoutFilter.createDefaultIdleDelayedExecutor();
delayedExecutor.start();
filterChainBuilder.add(new IdleTimeoutFilter(delayedExecutor, 30, TimeUnit.SECONDS, Connection::closeSilently));
filterChainBuilder.add(new TransportFilter());
Optional.ofNullable(filters).ifPresent(filterChainBuilder::addAll);
this.transport.setProcessor(filterChainBuilder.build());
doConnect();
}
protected void doConnect() {
if (this.closed) {
return;
}
while (!this.closed) {
try {
this.transport.start();
this.transport.connect(this.endpoint, new EmptyCompletionHandler<Connection>() {
@Override
public void failed(Throwable throwable) {
CompletableFuture.runAsync(() -> doConnect());
}
@Override
public void completed(Connection result) {
connection = result;
connection.addCloseListener((CloseListener) (closeable, iCloseType) -> CompletableFuture.runAsync(() -> doConnect()));
}
});
return;
} catch (Exception ignored) {
}
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}
public void sent(Object data) {
Optional.ofNullable(this.connection)
.filter(Connection::isOpen)
.ifPresent(x -> x.write(data));
}
}