-
Notifications
You must be signed in to change notification settings - Fork 6
Session
WIKI Home -> Session API docs
You will need an instance of NKNClient
NKNClient client = new NKNClient(new Identity("Name", Wallet.createNew()));
client.start();
As you can see, the client requires Identity
which is built from a friendly name, whatever you like (it may be null) and instance of Wallet
which you plan to use for this particular instance. Let's just generate a new one.
Session tunnel is a fully duplex reliable protocol, that uses multiple NKN clients to connect both parties together and transmits data using all connections in a load-balancing manner. It handles congestion control, packet drop, and re-sending, buffering, and order of packets of data.
For two sides to establish a session tunnel, one side must be in "server mode", which means awaiting an incoming connection and the other must dial this connection. After a session has been established everything is the same for both sides.
Assuming we already have a started client instance, let's set a callback for incoming sessions:
clientB.sessionProtocol().onSessionRequest(s -> {
// Prepare session, if it gets established
s.onSessionEstablished() {
// Do something, send or receive data
// This method shouldnt block, which means unless you are just setting a flag in your code somewhere, create a new thread
};
s.onSessionBrokenTunnel(() -> {
LOG.warn("Session tunnel broke");
});
// If incoming connection is from a whitelist of allowed nodes,
if (s.remoteIdentifier.equals("Friend.NKNaddress")) {
return true; // Accept the session
} else {
return false; // Drop the connection attempt
}
})
To dial a session, call:
Session s = client.sessionProtocol().dialSession(targetFullIdentifier);
and set session callbacks, same as before:
// Prepare session, if it gets established
s.onSessionEstablished() {
// Do something, send or receive data
// This method shouldnt block, which means unless you are just setting a flag in your code somewhere, create a new thread
};
s.onSessionBrokenTunnel(() -> {
LOG.warn("Session tunnel broke");
});
To use the (established) session, use get SessionInputStream and SessionOutputStream using:
final SessionInputStream nknIn = session.getInputStream();
final SessionOutputStream nknOut = session.getOutputStream();
On top of implementing standard java stream behavior, session streams provide additional methods. Most important is
nknOut.getUnconfirmedSentBytesCount();
which returns a number of bytes that have been written to the send queue, but not acknowledged as received from the other side. For any reason, let it be a slow network connection, full buffers, or dropped ACK packet.
You can use sessions with custom parameters, of course. Here is a list:
- Number of multiclients used
- PreferredMtu
- PreferredWinSize
Session param value used is minimum value of dialing and awaiting side. To set these parameters as awaiting side, use methods:
client.sessionProtocol().setIncomingPreferredMulticlients(8); // Default 4
client.sessionProtocol().setIncomingPreferredMtu(512); // In bytes, Default is 1024
client.sessionProtocol().setIncomingPreferredWinSize(8 * 1024 * 1024); // In bytes, default is 4K
as for dialing session, use dialSession overload
client.sessionProtocol().dialSession(String destinationFullIdentifier, int multiclients, String[] targetPrefixes, int maxMtu, int maxWindowSize)
targetPrefixes
is a String array such as __0__
, __1__
which are the prefixes of multiclient on which the server side is listening. Pass null
for default. Default are __${i}__
for i in range 0 to multiclient count. Listening side listens for a connection on empty prefix as well, but doesn't use it for actual communication.
Beware: Both NKN nodes and this sdk are still work in progress and anything can change or stop working at any time.