KryoNetty is a Java library that provides clean and simple API for efficient TCP client/server network communication using Netty. KryoNetty uses the Kryo serialization library to automatically and efficiently transfer object graphs across the network.
KryoNetty is very similar to KryoNet, which does the exact same thing but using its own NIO-based networking. KryoNet also has more features than KryoNetty.
KryoNetty
passes the configuration of the different components to the classes & references behind it.
KryoNetty kryoNetty = new KryoNetty()
.useLogging()
.useExecution()
.threadSize(16)
.inputSize(4096)
.outputSize(4096)
.maxOutputSize(-1)
.register(TestRequest.class);
Please note that Kryo gives every class an index-number. If you change the order, errors may occur if both programs do not have the same order of registered classes. To register more classes than one.
KryoNetty kryoNetty = new KryoNetty()
.useLogging()
.useExecution()
.threadSize(16)
.inputSize(4096)
.outputSize(4096)
.maxOutputSize(-1)
.register(
TestRequest.class,
TestResponse.class,
SomeClass.class,
Random.class
)
Or with index-ids:
KryoNetty kryoNetty = new KryoNetty()
.useLogging()
.useExecution()
.threadSize(16)
.inputSize(4096)
.outputSize(4096)
.maxOutputSize(-1)
.register(100, TestRequest.class)
.register(101, TestResponse.class)
.register(102, SomeClass.class)
.register(103, Random.class);
Every option returns the current instance of KryoNetty
Current Options:
useLogging()
- enables usage of
LoggingHandler.class
- default: false
- enables usage of
useExecution()
- enables usage of
EventExecutorGroup.class
- default: false
- enables usage of
threadSize()
- sets threads of
EventExecutorGroup.class
- default: 0
- sets threads of
inputSize()
- sets buffer-size of
Input.class
- default: 2048
- sets buffer-size of
outputSize()
- sets buffer-size of
Output.class
- default: 2048
- sets buffer-size of
maxOutputSize()
- sets max-buffer-size of
Output.class
- default: -1
- sets max-buffer-size of
To start the Server
, the following call start(int port)
is all you need. The Server
need a configured KryoNetty
instance as argument.
Server server = new Server(kryoNetty);
server.start(56566);
If you want to let the Server
run in another thread, use the ThreadedServer
. This starts the server in a Executors.newSingleThreadExecutor()
. Just replace Server
with ThreadedServer
:
Server server = new ThreadedServer(kryoNetty);
server.start(56566);
The Client
configuration works quite similar to the Server
. The only difference are the start(int port)
and connect(String host, int port)
method-calls.
Client client = new Client(kryoNetty);
client.connect("localhost", 56566);
Same way with the ThreadedClient
Client client = new ThreadedClient(kryoNetty);
client.connect("localhost", 56566);
In contrast to KryoNet, the event system works a little differently. First of all there are the three following events:
ConnectEvent
- server: new client connects
- client: client connects to server
DisconnectEvent
- server: client disconnects (server-side)
- client: client disconnects (client-side)
ReceiveEvent
- server: receives new object from client
- client: receives new object from server
Here are two possibilities to register a Listener
on an Event
:
Class implementing Listener
-Interface (recommended)
public class ConnectionListener implements NetworkListener {
@NetworkHandler
public void onConnect(ConnectEvent connectEvent) {
ChannelHandlerContext ctx = event.getCtx();
System.out.println("Server: Client connected: " + ctx.channel().remoteAddress());
}
}
// In main-method
server.eventHandler().register(new ConnectionListener());
New Listener
-Instance in register(NetworkListener listener)
:
server.eventHandler().register(new NetworkListener() {
@NetworkHandler
public void onConnect(DisconnectEvent event) {
ChannelHandlerContext ctx = event.getCtx();
System.out.println("Server: Client disconnected: " + ctx.channel().remoteAddress());
}
});
Here an example to process an object which is fired via a ReceiveEvent
.
public class ReceiveListener implements NetworkListener {
@NetworkHandler
public void onReceive(ReceiveEvent event) {
ChannelHandlerContext ctx = event.getCtx();
Object object = event.getObject();
System.out.println("Server: Client received: " + ctx.channel().remoteAddress() + "/" + object);
if(object instanceof Boolean) {
Boolean result = (Boolean) object;
System.out.println("Result is: " + result);
}
}
}
First of all add jitpack.io
as repository.
repositories {
maven { url 'https://jitpack.io' }
}
After that you can add it as dependency.
dependencies {
implementation 'com.github.EsotericSoftware:kryonetty:master-SNAPSHOT'
}
If you want to build kryonetty
from source, clone this repository and run ./gradlew buildKryoNetty
. The output-file will be in the directory: /build/libs/kryonetty-{version}-all.jar
Gradle downloads the required dependencies and inserts all components into the output-file.
If you are interested in the build task:
task buildKryoNetty(type: Jar) {
baseName = project.name + '-all'
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
## Why KryoSerialization
Why do we use Kryo and not for example the Netty ObjectEncoder? Quite simple. Kryo is noticeably faster and also easy to use.
(Benchmark links:)
- https://github.com/EsotericSoftware/kryo#benchmarks
- https://github.com/eishay/jvm-serializers/wiki
Since we work with a `Kryo`, `Input` & `Output` in a `Pool<?>` from `kryo-5.0.0`, classes are passed to the `KryoSerialization` constructor for registration & initialization.
For more documentation see `KryoSerialization.class`
Please use the [KryoNet discussion group](http://groups.google.com/group/kryonet-users) for [Kryo](https://github.com/EsotericSoftware/kryo)/[KryoNet](https://github.com/EsotericSoftware/kryonet)-specific support. <br>