-
Notifications
You must be signed in to change notification settings - Fork 6
TCPConnections
Real applications have - in most cases - two jobs to do on a network level:
- Offer other parties a way to set up a connection.
- Create a connection usually triggered by user input.
Solutions for those two jobs can become a quite complex, e.g. when it comes to scatternets. This core framework does not deal with those specifics but offers some help. A little TCP support is included, though. We discuss a simple example first. You should read it even it is not the recommended approach.
This example presumably helps to understand our EncounterManager which is frankly the only and strongly recommended way to implement a stable ASAP app.
A full and working example can be found in unit test connectAliceAndBob_2 in ConnectPeers.
// create a peer that can and should be used in a real app
ASAPConnectionHandler alicePeerFS = new ASAPPeerFS(TestConstants.ALICE_ID, aliceFolder, formats);
// better define well-known port number in a real app
int portNumber = TestHelper.getPortNumber();
StreamPairCreatedListenerImpl aliceStreamPairCreatedListener = new StreamPairCreatedListenerImpl(alice);
SocketFactory socketFactory = new SocketFactory(portNumber, aliceStreamPairCreatedListener);
Thread socketFactoryThread = new Thread(socketFactory);
socketFactoryThread.start();
SocketFactory is meant to run in a thread.
It creates a TCP server socket and accepts connection requests. StreamPairCreatedListener aliceStreamPairCreatedListener
is called whenever a new connection was established.
private class StreamPairCreatedListenerImpl implements StreamPairCreatedListener {
private final ASAPConnectionHandler connectionHandler;
StreamPairCreatedListenerImpl(ASAPConnectionHandler connectionHandler) {
this.connectionHandler = connectionHandler;
}
@Override
public void streamPairCreated(StreamPair streamPair) {
try {
this.connectionHandler.handleConnection(
streamPair.getInputStream(),
streamPair.getOutputStream());
} catch (IOException | ASAPException e) {
Log.writeLog(this, "problems handling connection: " + e.getLocalizedMessage());
}
}
}
Here is the StreamPairCreatedListener implementation from our example.
private class StreamPairCreatedListenerImpl implements StreamPairCreatedListener {
private final ASAPConnectionHandler connectionHandler;
StreamPairCreatedListenerImpl(ASAPConnectionHandler connectionHandler) {
this.connectionHandler = connectionHandler;
}
@Override
public void streamPairCreated(StreamPair streamPair) {
try {
this.connectionHandler.handleConnection(
streamPair.getInputStream(),
streamPair.getOutputStream());
} catch (IOException | ASAPException e) {
Log.writeLog(this, "problems handling connection: " + e.getLocalizedMessage());
}
}
}
It's a slim implementation. Each new connection is send to the peer to handle it (handleConnection
)
Connecting to an open TCP port does not require any further support. Soem code from our unit test example.
// peer as connection handler
ASAPConnectionHandler bob = new ASAPPeerFS(TestConstants.BOB_ID, bobFolder, formats);
// create a connection
// remote peer address comes most likely from user input
// real apps should define a well-known port
Socket socket = new Socket(addressRemotePeer, portNumber);
bob.handleConnection(socket.getInputStream(), socket.getOutputStream());
A real app will connect to other peers. That connection establishment might be initiated by user or happens on some regular intervals. In any case, the code above would connect to another peer and ask the local peer to run an ASAP session.
Using TCP as communication protocol is difficult. The little supported that is provided is hopefully nice but hardly necessary. But we ignored some issues which can sooner or later up in a real infrastructure. Just to name two:
- We call of those issues flickering. Especially in wireless ad-hoc networks connections break down and re-establishment alternates annoyingly quickly when they reach the perimeter communication range.
- Network connections can be a rare resource. In some environments, a device can only establish a single connection on a given protocol. It would be very helpful to close such idle connections. ASAP peers cannot create and will never close a connection, though.
Our EncounterManager helps.