*/
abstract class Server implements Runnable {
protected final String key;
+ protected long id = 0;
private final String name;
private final Object lock = new Object();
tracer.error(e);
}
+ /**
+ * Return the next ID to use.
+ *
+ * @return the next ID
+ */
+ protected synchronized long getNextId() {
+ return id++;
+ }
+
+ /**
+ * Method called when
+ * {@link ServerObject#onRequest(ConnectActionServerObject, Object, long)}
+ * has successfully finished.
+ * <p>
+ * Can be used to know how much data was transmitted.
+ *
+ * @param id
+ * the ID used to identify the request
+ * @param bytesReceived
+ * the bytes received during the request
+ * @param bytesSent
+ * the bytes sent during the request
+ */
+ @SuppressWarnings("unused")
+ protected void onRequestDone(long id, long bytesReceived, long bytesSent) {
+ }
+
/**
* Create a {@link Socket}.
*
return new ConnectActionServerObject(s, key) {
@Override
public void action() throws Exception {
+ long id = getNextId();
try {
for (Object data = rec(); true; data = rec()) {
Object rep = null;
try {
- rep = onRequest(this, data);
+ rep = onRequest(this, data, id);
if (isClosing()) {
return;
}
}
} catch (NullPointerException e) {
// Client has no data any more, we quit
+ onRequestDone(id, getBytesReceived(), getBytesSent());
}
}
* the client action
* @param data
* the data sent by the client (which can be NULL)
+ * @param id
+ * an ID to identify this request (will also be re-used for
+ * {@link ServerObject#onRequestDone(long, long, long)}.
*
* @return the answer to return to the client (which can be NULL)
*
* in case of an exception, the error will only be logged
*/
abstract protected Object onRequest(ConnectActionServerObject action,
- Object data) throws Exception;
+ Object data, long id) throws Exception;
}
return new ConnectActionServerString(s, key) {
@Override
public void action() throws Exception {
+ long id = getNextId();
for (String data = rec(); data != null; data = rec()) {
String rep = null;
try {
- rep = onRequest(this, data);
+ rep = onRequest(this, data, id);
if (isClosing()) {
return;
}
if (rep == null) {
rep = "";
}
-
send(rep);
}
+
+ onRequestDone(id, getBytesReceived(), getBytesSent());
}
@Override
* the client action
* @param data
* the data sent by the client
+ * @param id
+ * an ID to identify this request (will also be re-used for
+ * {@link ServerObject#onRequestDone(long, long, long)}.
*
* @return the answer to return to the client
*
* in case of an exception, the error will only be logged
*/
abstract protected String onRequest(ConnectActionServerString action,
- String data) throws Exception;
+ String data, long id) throws Exception;
}
ServerString server = new ServerString(this.getName(), 0, key) {
@Override
protected String onRequest(
- ConnectActionServerString action, String data)
- throws Exception {
+ ConnectActionServerString action, String data,
+ long id) throws Exception {
return null;
}
ServerString server = new ServerString(this.getName(), 0, key) {
@Override
protected String onRequest(
- ConnectActionServerString action, String data)
- throws Exception {
+ ConnectActionServerString action, String data,
+ long id) throws Exception {
sent[0] = data;
return "pong";
}
ServerString server = new ServerString(this.getName(), 0, key) {
@Override
protected String onRequest(
- ConnectActionServerString action, String data)
- throws Exception {
+ ConnectActionServerString action, String data,
+ long id) throws Exception {
sent[0] = data;
action.send("pong");
sent[1] = action.rec();
ServerString server = new ServerString(this.getName(), 0, key) {
@Override
protected String onRequest(
- ConnectActionServerString action, String data)
- throws Exception {
+ ConnectActionServerString action, String data,
+ long id) throws Exception {
sent[Integer.parseInt(data)] = data;
return "" + (Integer.parseInt(data) * 2);
}
ServerObject server = new ServerObject(this.getName(), 0, key) {
@Override
protected Object onRequest(
- ConnectActionServerObject action, Object data)
- throws Exception {
+ ConnectActionServerObject action, Object data,
+ long id) throws Exception {
return null;
}
ServerObject server = new ServerObject(this.getName(), 0, key) {
@Override
protected Object onRequest(
- ConnectActionServerObject action, Object data)
- throws Exception {
+ ConnectActionServerObject action, Object data,
+ long id) throws Exception {
sent[0] = data;
return "pong";
}
ServerObject server = new ServerObject(this.getName(), 0, key) {
@Override
protected Object onRequest(
- ConnectActionServerObject action, Object data)
- throws Exception {
+ ConnectActionServerObject action, Object data,
+ long id) throws Exception {
sent[0] = data;
action.send("pong");
sent[1] = action.rec();
ServerObject server = new ServerObject(this.getName(), 0, key) {
@Override
protected Object onRequest(
- ConnectActionServerObject action, Object data)
- throws Exception {
+ ConnectActionServerObject action, Object data,
+ long id) throws Exception {
sent[0] = data;
return new Object[] { "ACK" };
}
ServerObject server = new ServerObject(this.getName(), 0, key) {
@Override
protected Object onRequest(
- ConnectActionServerObject action, Object data)
- throws Exception {
+ ConnectActionServerObject action, Object data,
+ long id) throws Exception {
sent[(Integer) data] = data;
return ((Integer) data) * 2;
}