You are viewing our Forum Archives. To view or take place in current topics click here.
[Java] KryoNet Networking Tutorial
Posted:

[Java] KryoNet Networking TutorialPosted:

_Atrium
  • New Member
Status: Offline
Joined: Mar 24, 20159Year Member
Posts: 34
Reputation Power: 1
Status: Offline
Joined: Mar 24, 20159Year Member
Posts: 34
Reputation Power: 1
Please understand, I did not write Kryo, nor the components. I'm simply supporting the network system, and posting a tutorial for all of you!



What is KryoNet, and why should I use it?
KryoNet is quite simply a java networking library, that takes the massive, often overwhelming amount of networking classes, and shrinks them down to what you'll need to produce a fully functional server and client. KryoNet, similar to many other networking libraries, can be used to make many things. One example within the GitHub repository is a chat server, another a player position server. Since I mostly write games, that's the approach I'll be taking in this tutorial. I'm fully aware that there is a documented guide on how to do various things within the Git, but I'm aiming to write this tutorial, explain what is happening, and then provide support for questions and concerns. Without further ado, let's get started!


How to start the server...
KryoNet allows for easy networking on a server, because rather than writing multiple methods for binding the server, there's simply one 'Server' class within the Kryo library that does all of that for us. First things first, you'll need to create a Server object, then import the Server class from the Kryo library.
Server server = new Server();

What this line of code is doing is simple: creating an object of the Server class, and then calling the constructor, which will eventually provide some helpful code for binding the server. At this point, there is one very simple method within the Server class that will start the network procedure. This method is entitled, start. So, this translates to...
Server server = new Server();
server.start();

We're taking our server object, and calling the 'start' method, which will configure out network for binding. Once we've configured our network with the start procedure, we can bind the network. KryoNet is slightly different from some network libraries in the sense that rather than using a single port to bind to, KryoNet uses both a TCP port and UDP port. For quick explanation, a TCP port is used for reliable delivery of streams over a network connection, while a UDP port sends messages entitled datagrams, which are most often referred to as packets, over a network connection. These are seperated with Kryo. To bind the server to the ports, we simply call the bind method within our server object. The order of ports is TCP, followed by UDP.
Server server = new Server();
server.start();
server.bind(54555, 54777)

Once your server is bound to the ports, we're ready to allow for receiving objects within the network. A common object would be the login procedure, or for more advanced games, a handshake procedure. Any object will do, as long as there is both a request and a response. For exemplary purposes, I'll simply be entitling these classes 'SampleRequest' and 'SampleResponse'. Before allowing these objects, we'll need to register them within the Kryo network. To do this, we simply call these objects following the bind method.
Server server = new Server();
server.start();
server.bind(54555, 54777)

Kryo kryo = server.getKryo();
kryo.register(SampleRequest.class);
kryo.register(SampleResponse.class);

Once we register the classes, we can allow for the receiving of the classes. Within Kryo's server class is a method entitled addListener, which uses the Listener class to 'listen' for events. Events could be anything, but as I said, we'll be using the 'Sample' classes. Once our listener has been instantiated, we create a method entitled 'received', which represents that the listener has received a message (or an event). This method will be followed with the parameters of Connection connection, and Object object, representing the connection from which the object is received. Within our received method, we use of instanceof checks to dictate how the server will react to an object being received. In this case, the 'SampleRequest' would be the instance, and that's what were responding to. Using our common sense, we called the request, followed by the response. We'll print the variable 'text' line from the 'SampleRequest' to assure ourselves that the request has been registered. Now that our request has been called, we can call our response. Once our response has been called, we'll print the variable 'text' line from the response class as well, a simple check that we've reached our goal. Here is what our code looks like at this point...
Server server = new Server();
server.start();
server.bind(54555, 54777)

Kryo kryo = server.getKryo();
kryo.register(SampleRequest.class);
kryo.register(SampleResponse.class);

server.addListener(new Listener() {
        public void received (Connection connection, Object object) {
              if (object instanceof SampleRequest) {
                 SampleRequest request = (SampleRequest)object;
                 System.out.println(request.text);

                 SampleResponse response = new SampleResponse();
                 System.out.println(response.text);
              }
           }
        });

Now that we've gotten the response to the request, we need to simply send the response over the TCP port, or the parameter 'connection'. Simply put, we use the method sendTCP to send the information over the TCP port. This is what our final server product will look like.
Server server = new Server();
server.start();
server.bind(54555, 54777)

Kryo kryo = server.getKryo();
kryo.register(SampleRequest.class);
kryo.register(SampleResponse.class);

server.addListener(new Listener() {
        public void received (Connection connection, Object object) {
              if (object instanceof SampleRequest) {
                 SampleRequest request = (SampleRequest)object;
                 System.out.println(request.text);

                 SampleResponse response = new SampleResponse();
                 System.out.println(response.text);
                      connection.sendTCP(response);
              }
           }
        });



How to start the client...
Starting the client is extremely similar to starting the server. Rather than an abundance of implemented classes, we use one simple class from the Kryo library; Client. We create a new Client object, and use the start method to start the client configuration. Here's where the difference is. Rather than binding a server to a port, we're opening a client up to a specific address. The method is called 'connect', but it has a few parameters to go along with it. Here's a list of the parameters.
    Connection block time - blocks the connection for a specified time. If the connection has an error, an exception is thrown. Please note that the integer within this param represents that amount in milliseconds.
    Server host - more simply put, the IP address to listen on. For this example, I'll be using the default local host.
    TCP Port - should be the same as the TCP port in the server.
    UDP Port - should be the same as the UDP port in the server.

At this point, this is what our code should look like.
Client client = new Client();
client.start();
client.connect(5000, "127.0.0.1", 54555, 54777);

Extremely similar to the server , we need to register the used classes. Rather than calling the kryo's server, we use the client's getKryo method to retrieve the kryo network. Then we can register classes the exact same way as the server. In the client, this is where we would state the request. First, we create a new SampleRequest object. Feel free to send the same text from the server example, but at this point, you can rest assured that the request is gotten. Using the client's object, we then use the same sendTCP method, and send the request over the network. Here is what our code looks like now.
Client client = new Client();
client.start();
client.connect(5000, "127.0.0.1", 54555, 54777);
      
Kryo kryoClient = client.getKryo();
kryoClient.register(SampleRequest.class);
kryoClient.register(SampleResponse.class);

SampleRequest request = new SampleRequest();
client.sendTCP(request);

At this point, we use the addListener method to add a listener instance, then create a method for the received event. Within this method, we use similar instanceof checks, but instead of checking for the instance of a request, the client checks for the instance of a response. Since the server will be sending the request, it makes sense the client will be reading the response. The structure of the client's addListener method, in terms of how we write our received method, is identical. Knowing that, we can simply transfer the code over to the client, then modify the request statements with return statements. This is how the code will look at this point.
Client client = new Client();
client.start();
client.connect(5000, "127.0.0.1", 54555, 54777);
      
Kryo kryoClient = client.getKryo();
kryoClient.register(SampleRequest.class);
kryoClient.register(SampleResponse.class);

SampleRequest request = new SampleRequest();
client.sendTCP(request);

client.addListener(new Listener() {
   public void received (Connection connection, Object object) {
              if (object instanceof SampleResponse) {
                 SampleResponse response = (SampleResponse)object;
                 System.out.println(response.text);
              }
           }
   });



Follow Up Section
Please note that this was my first tutorial, and it's also 11:15 PM my time, so it may not be the greatest upon first arrival. However, I'm hoping someone can benefit from this. If anyone would like to see a working example of a Kryo client-server, I can definitely post one up per request. I'm using this scheme for the game I'm developing, and would definitely recommend this network library to anyone looking to understand networking in Java.

Any questions or concerns can be posted below, thanks for reading!
#2. Posted:
_Atrium
  • New Member
Status: Offline
Joined: Mar 24, 20159Year Member
Posts: 34
Reputation Power: 1
Status: Offline
Joined: Mar 24, 20159Year Member
Posts: 34
Reputation Power: 1
Was this helpful for anyone? Hoping to get some sort of response haha. I love hearing feedback!
Jump to:
You are viewing our Forum Archives. To view or take place in current topics click here.