Make tcp handlers more generic

This commit is contained in:
Arnaud Vergnet 2021-01-07 15:35:05 +01:00
parent 7a36ef2c60
commit 1cf1ebec37
10 changed files with 91 additions and 47 deletions

View file

@ -11,14 +11,14 @@ import java.net.Socket;
public class PeerHandshake {
private PeerConnection connection;
private TcpConnection connection;
private UserInformation userInformation;
public void createConnection(InetAddress ipAddr, UserConnectedCallback callback, ErrorCallback errorCallback) {
closeConnection();
Log.v(this.getClass().getSimpleName(), "Creating new TCP connection ");
connection = new PeerConnection(
connection = new TcpConnection(
ipAddr,
(thisConnection) -> init(thisConnection,
false,
@ -33,11 +33,11 @@ public class PeerHandshake {
public void acceptConnection(Socket socket, UserConnectedCallback callback, ErrorCallback errorCallback) {
closeConnection();
connection = new PeerConnection(socket);
connection = new TcpConnection(socket);
init(connection, true, callback, errorCallback);
}
private void init(PeerConnection thisConnection, boolean isReceiving, UserConnectedCallback callback, ErrorCallback errorCallback) {
private void init(TcpConnection thisConnection, boolean isReceiving, UserConnectedCallback callback, ErrorCallback errorCallback) {
// Send our username
thisConnection.send(new UserInformation(CurrentUser.getInstance()), null, e -> {
closeConnection();
@ -68,7 +68,7 @@ public class PeerHandshake {
});
}
private void sendUsernameTaken(PeerConnection thisConnection) {
private void sendUsernameTaken(TcpConnection thisConnection) {
Log.v(this.getClass().getSimpleName(), "Received username request using current username");
thisConnection.send(new UsernameTakenException("Username taken"), this::closeConnection, null);
}
@ -84,7 +84,7 @@ public class PeerHandshake {
}
}
public PeerConnection getConnection() {
public TcpConnection getConnection() {
return connection;
}

View file

@ -11,13 +11,14 @@ import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
public class PeerConnection {
public static final short TCP_PORT = 31598;
public class TcpConnection {
public static final int TCP_PORT = 31598;
private Socket socket;
private ObjectOutputStream outputStream;
private ObjectInputStream inputStream;
private boolean shouldStop = false;
private final int port;
/**
* Creates a new connection, and connects to the peer
@ -26,7 +27,19 @@ public class PeerConnection {
* @param callback The function to call when connected
* @param errorCallback The function to call on error
*/
public PeerConnection(InetAddress ipAddr, SocketConnectedCallback callback, ErrorCallback errorCallback) {
public TcpConnection(InetAddress ipAddr, SocketConnectedCallback callback, ErrorCallback errorCallback) {
this(ipAddr, TCP_PORT, callback, errorCallback);
}
/**
* Creates a new connection, and connects to the peer
*
* @param ipAddr The IP address of the peer
* @param callback The function to call when connected
* @param errorCallback The function to call on error
*/
public TcpConnection(InetAddress ipAddr, int port, SocketConnectedCallback callback, ErrorCallback errorCallback) {
this.port = port;
Connector connector = new Connector(ipAddr, callback, errorCallback);
connector.start();
}
@ -36,7 +49,8 @@ public class PeerConnection {
*
* @param socket A socket already connected to the host
*/
public PeerConnection(Socket socket) {
public TcpConnection(Socket socket) {
this.port = socket.getPort();
this.socket = socket;
}
@ -53,7 +67,7 @@ public class PeerConnection {
}
/**
* Subscibe to all incoming messages from the peer
* Subscribe to all incoming messages from the peer
*
* @param callback The function to call when a message is received
* @param errorCallback The function to call on error
@ -89,7 +103,7 @@ public class PeerConnection {
/**
* Checks if the current connection is open
* @return True if the socket isstill open
* @return True if the socket is still open
*/
public boolean isOpen() {
return socket != null && socket.isConnected() && !socket.isClosed();
@ -112,8 +126,8 @@ public class PeerConnection {
if (socket != null) {
close();
}
socket = new Socket(ipAddr, TCP_PORT);
callback.onSocketConnected(PeerConnection.this);
socket = new Socket(ipAddr, port);
callback.onSocketConnected(TcpConnection.this);
} catch (IOException e) {
if (errorCallback != null)
errorCallback.onError(e);
@ -130,12 +144,12 @@ public class PeerConnection {
/**
* Constructs a thread that sends a message using the socket of the outer class
*
* @param messsage The message to send
* @param message The message to send
* @param callback The function to call on success
* @param errorCallback The function to call on error
*/
public Sender(Serializable messsage, @Nullable MessageSentCallback callback, @Nullable ErrorCallback errorCallback) {
this.message = messsage;
public Sender(Serializable message, @Nullable MessageSentCallback callback, @Nullable ErrorCallback errorCallback) {
this.message = message;
this.callback = callback;
this.errorCallback = errorCallback;
}
@ -191,7 +205,7 @@ public class PeerConnection {
public interface SocketConnectedCallback {
void onSocketConnected(PeerConnection connection);
void onSocketConnected(TcpConnection connection);
}
public interface MessageReceivedCallback {

View file

@ -6,19 +6,19 @@ import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import static fr.insa.clavardator.network.PeerConnection.TCP_PORT;
import static fr.insa.clavardator.network.TcpConnection.TCP_PORT;
public class ConnectionListener {
public class TcpListener {
Acceptor acceptor = null;
public ConnectionListener() {
public TcpListener() {
}
/**
* Start accepting incoming connections
*
* @param callback The function to call when a user connects
* @param errorCallback The function to call on errror
* @param errorCallback The function to call on error
*/
public void acceptConnection(NewConnectionCallback callback, ErrorCallback errorCallback) {
if (acceptor != null) {

View file

@ -1,8 +1,11 @@
package fr.insa.clavardator.server;
import fr.insa.clavardator.network.PeerConnection;
import fr.insa.clavardator.network.TcpConnection;
import fr.insa.clavardator.users.UserInformation;
import fr.insa.clavardator.util.ErrorCallback;
import fr.insa.clavardator.util.ParametrizedCallback;
import fr.insa.clavardator.util.SimpleCallback;
import java.net.InetAddress;
import java.util.ArrayList;
/**
@ -33,22 +36,22 @@ public class InsaPresence implements Presence {
}
@Override
public ArrayList<String> subscribe() {
return null;
}
@Override
public void unsubscribe() {
public void subscribe(ParametrizedCallback<ArrayList<UserInformation>> callback, ErrorCallback errorCallback) {
}
@Override
public void publish(boolean connected) {
public void unsubscribe(SimpleCallback callback, ErrorCallback errorCallback) {
}
@Override
public PeerConnection getProxyConnection() {
public void publish(boolean connected, SimpleCallback callback, ErrorCallback errorCallback) {
}
@Override
public TcpConnection getProxyConnection() {
return null;
}
}

View file

@ -1,24 +1,38 @@
package fr.insa.clavardator.server;
import fr.insa.clavardator.network.PeerConnection;
import fr.insa.clavardator.network.TcpConnection;
import fr.insa.clavardator.users.UserInformation;
import fr.insa.clavardator.util.ErrorCallback;
import fr.insa.clavardator.util.ParametrizedCallback;
import fr.insa.clavardator.util.SimpleCallback;
import java.util.ArrayList;
/**
* Interface exposing public methods necessary for any presence server.
*
* @implNote Implement this interface when creating your own presence server class,
* then update the {@link fr.insa.clavardator.server.PresenceFactory factory}
* to add your new implementation.
*/
public interface Presence {
/**
* Subscribes to this presence server notifications.
* A list of Ids representing the current active users is returned.
*
* @return The list of connected user's Ids
* @param callback Called when subscription completes
*/
ArrayList<String> subscribe();
void subscribe(ParametrizedCallback<ArrayList<UserInformation>> callback, ErrorCallback errorCallback);
/**
* Stops subscription to the presence server.
* Stops subscription to the presence server by closing TCP connections.
* This will stop notifications.
*
* @implNote Call this before exiting the app.
* If not, the presence server will wait for a tcp timeout before marking this user as disconnected.
*/
void unsubscribe();
void unsubscribe(SimpleCallback callback, ErrorCallback errorCallback);
/**
* Updates the current user state on the server.
@ -27,7 +41,7 @@ public interface Presence {
*
* @param connected The new user state
*/
void publish(boolean connected);
void publish(boolean connected, SimpleCallback callback, ErrorCallback errorCallback);
/**
@ -38,5 +52,5 @@ public interface Presence {
*
* @return The server address
*/
PeerConnection getProxyConnection();
TcpConnection getProxyConnection();
}

View file

@ -1,5 +1,8 @@
package fr.insa.clavardator.server;
/**
* Static factory class used to create concrete presence server implementations.
*/
public class PresenceFactory {
public static Presence create(PresenceType type, String uri, int serverPort, int proxyPort) throws UnknownPresenceException {
switch (type) {

View file

@ -5,7 +5,7 @@ import fr.insa.clavardator.chat.FileMessage;
import fr.insa.clavardator.chat.Message;
import fr.insa.clavardator.db.DatabaseController;
import fr.insa.clavardator.errors.UsernameTakenException;
import fr.insa.clavardator.network.PeerConnection;
import fr.insa.clavardator.network.TcpConnection;
import fr.insa.clavardator.util.ErrorCallback;
import fr.insa.clavardator.util.Log;
import org.jetbrains.annotations.NotNull;
@ -19,7 +19,7 @@ import java.util.Date;
public class PeerUser extends User implements Comparable<PeerUser> {
protected transient ChatHistory history;
private State state = State.DISCONNECTED;
private transient PeerConnection connection;
private transient TcpConnection connection;
public PeerUser(String id, String username) {
super(id, username);
@ -98,12 +98,12 @@ public class PeerUser extends User implements Comparable<PeerUser> {
}
}
private void sendUsernameTaken(PeerConnection thisConnection) {
private void sendUsernameTaken(TcpConnection thisConnection) {
Log.v(this.getClass().getSimpleName(), "Received username request using current username");
thisConnection.send(new UsernameTakenException("Username taken"), this::disconnect, null);
}
public void init(PeerConnection connection, String id, String username, ErrorCallback errorCallback) {
public void init(TcpConnection connection, String id, String username, ErrorCallback errorCallback) {
this.connection = connection;
this.id = id;
setUsername(username);

View file

@ -2,7 +2,7 @@ package fr.insa.clavardator.users;
import fr.insa.clavardator.config.Config;
import fr.insa.clavardator.db.DatabaseController;
import fr.insa.clavardator.network.ConnectionListener;
import fr.insa.clavardator.network.TcpListener;
import fr.insa.clavardator.network.NetDiscoverer;
import fr.insa.clavardator.network.PeerHandshake;
import fr.insa.clavardator.server.Presence;
@ -27,7 +27,7 @@ public class UserList {
private final ObservableList<PeerUser> userObservableList = FXCollections.observableArrayList();
private final DatabaseController db = new DatabaseController();
private final NetDiscoverer netDiscoverer = new NetDiscoverer();
private final ConnectionListener connectionListener = new ConnectionListener();
private final TcpListener tcpListener = new TcpListener();
private Presence presenceServer;
@ -74,7 +74,7 @@ public class UserList {
* @param errorCallback Callback on error
*/
public void startUserListening(ErrorCallback errorCallback) {
connectionListener.acceptConnection(
tcpListener.acceptConnection(
(clientSocket) -> {
Log.v(this.getClass().getSimpleName(),
"new connection from user at address: " + clientSocket.getInetAddress().toString());
@ -162,7 +162,7 @@ public class UserList {
*/
public void destroy() {
netDiscoverer.stopDiscovery();
connectionListener.stopAccepting();
tcpListener.stopAccepting();
db.close();
for (PeerUser user : userHashmap.values()) {
user.disconnect();

View file

@ -0,0 +1,5 @@
package fr.insa.clavardator.util;
public interface ParametrizedCallback<T> {
void call(T param);
}

View file

@ -0,0 +1,5 @@
package fr.insa.clavardator.util;
public interface SimpleCallback {
void call();
}