- Provide a simple, efficient and high level interface to open a server and connect to servers
- Send custom packets over the given connections effortlessly and without any boilerplate code
- Give the user the opportunity to make the entire client-server interaction asynchronous
- Be modular, so more io library adapter can be written
- Be fast
Every operation in this API uses the Operation
interface.
For example send a client a packet returns such an operation.
Using this operation you may execute Operation#complete
(synchronized) or Operation#queue
(async).
Operations are immutable and the methods mentioned above will return itself for executing itself multiple times.
Some asynchronous operations use a centralized thread pool, they may also use a local thread pool depending on the operation.
You may also configure your own thread pool with the provided factories.
If you want to use custom packets, you may register your packets in the PacketRegistry
.
You may want to watch out of registering a packet with an existing packet id. You can find a list of default packets here.
The first interaction between the server and the client will always be handshake for checking the versions etc.
Furthermore, the client and the server are both implementing NetworkAdapter.
There is also an event system. You can find more details here.
Currently there is also an implementation for sending large files.
For that, use the FileClient.
ATM there is just an java.net.Socket implementation of server and client.
The API design supports more implementations, so I hope for more to come!
First of all you need a SocketServerBuilder
to create a new Server
Instance.
With this builder, you are able to configure (tickrate, encryption, ...) your server.
Using SocketServerBuilder#build
you build your configurated server. Congratulations!
Server server = new SocketServerBuilder().build(PORT);
Every connecting client will receive a Handshake for checking the API version, not answering this handshake will result in shutting down the client.
You are also able to prevent the server from accepting new clients using Server#close
or shut it down entirely by using Server#shutdown
Opening a new client is fairly simple.
Client client = new SocketClientBuilder().build(ADDRESS, PORT);
Now, if you also want to receive packets, you may also open your client. Otherwise your client will only be able to send packets.
You may use Client#open
for that. You are also able to close the client or shut it down entirely.
Almost every central API object is an EventHandlerContainer
, which means you can use its EventHandler to subscribe to the events of the API object.
For example the Server
will notify you about every incoming connection if you've subscribe using the ClientConnectEvent
.
server.getEventHandler().subscribe(ClientConnectEvent.class, (connectEvent) -> System.out.println("Connected client " + connectEvent.client().getAddress().toString()));
Some events implement Cancellable
. Some of these events can be cancelled using Cancellable#behaviour#setCancelled
.
In addition to that, all events are records.
NetworkAdapter events:
- AdapterOpenEvent - Triggered when an adapter has been opened
- AdapterCloseEvent - Triggered when an adapter has been closed
- AdapterShutdownEvent - Triggered when an adapter has been shutdown
Server events:
- ClientConnectEvent - Triggered when a client connects to a server
Client events:
- PacketSendEvent - Triggered when a packet has been sent
- PacketReceiveEvent - Triggered when a packet has been received
Following IDs for packets are already used any may not be used by the user again:
The following IDs are completely random.
- 69420: HandshakePacket
- 69421: FileHeaderPacket
- 69422: FileDataPacket
- 69423: FileTransferredPacket
The via de.lama.packets.stream transmitted packets have fixed structure:
- A char which contains the type of the following data, if its a Packet is 'p' (1 byte)
- A long which contains the ID of the following packet (8 bytes)
- An int which contains the size of the incoming packet (4 bytes)
- The packet in the format given by the wrapper. Default is UTF-8 encoded JSON (x bytes)
Packets transmitted using the CachedGsonWrapper (default) will use a cache, which will significantly improve performance on heavy packet load, if multiple packets with the same hash will be sent.
- Encryption
- More implementations
- More events
- PacketCompression?
- Better builder