package be.nikiroo.utils.serial.server; import java.net.Socket; import be.nikiroo.utils.Version; /** * Base class used for the server basic handling. *

* It represents a single action: a server is expected to execute one action for * each client action. * * @author niki */ abstract class ConnectActionServer { private boolean closing; /** * The underlying {@link ConnectAction}. *

* Cannot be NULL. */ protected ConnectAction action; /** * Create a new {@link ConnectActionServer}, using the current version. * * @param s * the socket to bind to * @param key * an optional key to encrypt all the communications (if NULL, * everything will be sent in clear text) */ public ConnectActionServer(Socket s, String key) { this(s, key, Version.getCurrentVersion()); } /** * Create a new {@link ConnectActionServer}. * * @param s * the socket to bind to * @param key * an optional key to encrypt all the communications (if NULL, * everything will be sent in clear text) * @param serverVersion * the version of this server,that will be sent to the client */ public ConnectActionServer(Socket s, String key, Version serverVersion) { action = new ConnectAction(s, true, key, serverVersion) { @Override protected void action(Version clientVersion) throws Exception { ConnectActionServer.this.action(clientVersion); } @Override protected void onError(Exception e) { ConnectActionServer.this.onError(e); } @Override protected Version negotiateVersion(Version clientVersion) { return ConnectActionServer.this.negotiateVersion(clientVersion); } }; } /** * Actually start the process and call the action (synchronous). */ public void connect() { action.connect(); } /** * Actually start the process and call the action (asynchronous). */ public void connectAsync() { new Thread(new Runnable() { @Override public void run() { connect(); } }).start(); } /** * Stop the client/server connection on behalf of the server (usually, the * client connects then is allowed to send as many requests as it wants; in * some cases, though, the server may wish to forcefully close the * connection and can do via this value, when it is set to TRUE). *

* Example of usage: the client failed an authentication check, cut the * connection here and now. * * @return TRUE when it is */ public boolean isClosing() { return closing; } /** * Can be called to stop the client/server connection on behalf of the * server (usually, the client connects then is allowed to send as many * requests as it wants; in some cases, though, the server may wish to * forcefully close the connection and can do so by calling this method). *

* Example of usage: the client failed an authentication check, cut the * connection here and now. */ public void close() { closing = true; } /** * The total amount of bytes received. * * @return the amount of bytes received */ public long getBytesReceived() { return action.getBytesReceived(); } /** * The total amount of bytes sent. * * @return the amount of bytes sent */ public long getBytesSent() { return action.getBytesWritten(); } /** * Method that will be called when an action is performed on the server. * * @param clientVersion * the version of the client connected to this server * * @throws Exception * in case of I/O error */ @SuppressWarnings("unused") public void action(Version clientVersion) throws Exception { } /** * Handler called when an unexpected error occurs in the code. *

* Will just ignore the error by default. * * @param e * the exception that occurred */ protected void onError(@SuppressWarnings("unused") Exception e) { } /** * Method called when we negotiate the version with the client. *

* Will return the actual server version by default. * * @param clientVersion * the client version * * @return the version to send to the client */ protected Version negotiateVersion( @SuppressWarnings("unused") Version clientVersion) { return action.getVersion(); } }