* Finished server block.

This commit is contained in:
Nicolas BARBOTIN 2018-02-09 17:40:22 +01:00
parent 9789daa33e
commit e2a784e5e9
9 changed files with 74 additions and 11 deletions

View File

@ -4,7 +4,6 @@ This is the unfinished port of the WebDisplays mod for Minecraft 1.12.2. The tex
### Missing features ### Missing features
* Peripheral: OpenComputers interface * Peripheral: OpenComputers interface
* Read config (see "Config elements" below) * Read config (see "Config elements" below)
* Miniserv timeout
### TODO ### TODO
* French translations * French translations

View File

@ -52,6 +52,7 @@ import net.montoyo.wd.core.JSServerRequest;
import net.montoyo.wd.data.GuiData; import net.montoyo.wd.data.GuiData;
import net.montoyo.wd.entity.TileEntityScreen; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.item.ItemMulti; import net.montoyo.wd.item.ItemMulti;
import net.montoyo.wd.miniserv.Constants;
import net.montoyo.wd.miniserv.client.Client; import net.montoyo.wd.miniserv.client.Client;
import net.montoyo.wd.net.server.SMessagePadCtrl; import net.montoyo.wd.net.server.SMessagePadCtrl;
import net.montoyo.wd.net.server.SMessageScreenCtrl; import net.montoyo.wd.net.server.SMessageScreenCtrl;
@ -87,6 +88,8 @@ public class ClientProxy extends SharedProxy implements IResourceManagerReloadLi
private MinePadRenderer minePadRenderer; private MinePadRenderer minePadRenderer;
private JSQueryDispatcher jsDispatcher; private JSQueryDispatcher jsDispatcher;
private LaserPointerRenderer laserPointerRenderer; private LaserPointerRenderer laserPointerRenderer;
//Miniserv handling
private int miniservPort; private int miniservPort;
private boolean msClientStarted; private boolean msClientStarted;
@ -550,8 +553,8 @@ public class ClientProxy extends SharedProxy implements IResourceManagerReloadLi
//Handle JS queries //Handle JS queries
jsDispatcher.handleQueries(); jsDispatcher.handleQueries();
//Stop miniserv client //Miniserv
if(mc.player == null && msClientStarted) { if(msClientStarted && mc.player == null) {
msClientStarted = false; msClientStarted = false;
Client.getInstance().stop(); Client.getInstance().stop();
} }

View File

@ -644,6 +644,12 @@ public class GuiServer extends WDScreen {
queueTask(task); queueTask(task);
} }
@CommandHandler("reconnect")
public void commandReconnect() {
Client.getInstance().stop();
WebDisplays.NET_HANDLER.sendToServer(Client.getInstance().beginConnection());
}
private void startFileUpload(File f, boolean quit) { private void startFileUpload(File f, boolean quit) {
if(quit) if(quit)
quitUploadWizard(); quitUploadWizard();

View File

@ -50,7 +50,7 @@ public abstract class AbstractClient {
protected abstract void onWriteError(); protected abstract void onWriteError();
public void readyRead(ByteBuffer bb) { public final void readyRead(ByteBuffer bb) {
while(bb.remaining() > 0) { while(bb.remaining() > 0) {
if(packetReader.readFrom(bb)) { //End of packet if(packetReader.readFrom(bb)) { //End of packet
byte[] pkt = packetReader.getPacketData(); byte[] pkt = packetReader.getPacketData();
@ -79,14 +79,18 @@ public abstract class AbstractClient {
packetReader.reset(); packetReader.reset();
} }
} }
onDataReceived();
} }
public void readyWrite() throws Throwable { public final void readyWrite() throws Throwable {
if(sendBuffer.remaining() > 0 || fillSendBuffer()) { if(sendBuffer.remaining() > 0 || fillSendBuffer()) {
int sent = socket.write(sendBuffer); int sent = socket.write(sendBuffer);
if(sent < 0) if(sent < 0)
onWriteError(); onWriteError();
else if(sent > 0)
onDataSent();
} }
} }
@ -115,7 +119,7 @@ public abstract class AbstractClient {
return pos > 0; return pos > 0;
} }
public void sendPacket(OutgoingPacket pkt) { public final void sendPacket(OutgoingPacket pkt) {
synchronized(sendQueue) { synchronized(sendQueue) {
sendQueue.offer(pkt); sendQueue.offer(pkt);
@ -138,15 +142,21 @@ public abstract class AbstractClient {
} }
} }
protected byte[] getCurrentPacketRawData() { protected final byte[] getCurrentPacketRawData() {
return packetReader.getPacketData(); return packetReader.getPacketData();
} }
protected void clearSendQueue() { protected final void clearSendQueue() {
synchronized(sendQueue) { synchronized(sendQueue) {
packetWriter.clear(); packetWriter.clear();
sendQueue.clear(); sendQueue.clear();
} }
} }
protected void onDataReceived() {
}
protected void onDataSent() {
}
} }

View File

@ -22,4 +22,7 @@ public abstract class Constants {
public static int GETF_STATUS_CONNECTION_LOST = 4; public static int GETF_STATUS_CONNECTION_LOST = 4;
public static int GETF_STATUS_TIMED_OUT = 5; public static int GETF_STATUS_TIMED_OUT = 5;
public static long CLIENT_TIMEOUT = 30000L;
public static long CLIENT_PING_PERIOD = 5000L;
} }

View File

@ -47,6 +47,7 @@ public class Client extends AbstractClient implements Runnable {
private final ArrayDeque<ClientTask> tasks = new ArrayDeque<>(); private final ArrayDeque<ClientTask> tasks = new ArrayDeque<>();
private ClientTask currentTask; private ClientTask currentTask;
private volatile boolean authenticated; private volatile boolean authenticated;
private long lastPingTime;
public SMessageMiniservConnect beginConnection() { public SMessageMiniservConnect beginConnection() {
if(keyPair == null) { if(keyPair == null) {
@ -173,6 +174,7 @@ public class Client extends AbstractClient implements Runnable {
connPacket.writeLong(clientUUID.getMostSignificantBits()); connPacket.writeLong(clientUUID.getMostSignificantBits());
connPacket.writeLong(clientUUID.getLeastSignificantBits()); connPacket.writeLong(clientUUID.getLeastSignificantBits());
sendPacket(connPacket); sendPacket(connPacket);
lastPingTime = System.currentTimeMillis();
while(getRunning()) { while(getRunning()) {
try { try {
@ -214,7 +216,8 @@ public class Client extends AbstractClient implements Runnable {
} }
private void unsafeLoop() throws Throwable { private void unsafeLoop() throws Throwable {
selector.select(); long timeBeforePing = Constants.CLIENT_PING_PERIOD - (System.currentTimeMillis() - lastPingTime);
selector.select(Math.max(0, timeBeforePing));
if(currentTask == null || currentTask.isCanceled()) if(currentTask == null || currentTask.isCanceled())
nextTask(); nextTask();
@ -243,6 +246,14 @@ public class Client extends AbstractClient implements Runnable {
} }
} }
} }
long t = System.currentTimeMillis();
if(t - lastPingTime >= Constants.CLIENT_PING_PERIOD) {
OutgoingPacket pkt = new OutgoingPacket();
pkt.writeByte(PacketID.PING.ordinal());
sendPacket(pkt);
lastPingTime = t;
}
} }
@Override @Override
@ -326,6 +337,10 @@ public class Client extends AbstractClient implements Runnable {
((ClientTaskDeleteFile) currentTask).onStatusPacket(dis.readByte()); ((ClientTaskDeleteFile) currentTask).onStatusPacket(dis.readByte());
} }
@PacketHandler(PacketID.PING)
public void handlePing(DataInputStream dis) {
}
public void nextTask() { public void nextTask() {
if(currentTask != null) if(currentTask != null)
currentTask.onFinished(); currentTask.onFinished();
@ -365,4 +380,9 @@ public class Client extends AbstractClient implements Runnable {
selector.wakeup(); selector.wakeup();
} }
@Override
protected void onDataSent() {
lastPingTime = System.currentTimeMillis();
}
} }

View File

@ -131,7 +131,7 @@ public class Server implements Runnable {
} }
private void loopUnsafe() throws Throwable { private void loopUnsafe() throws Throwable {
selector.select(); selector.select(1000); //Allow the server to kick timed-out clients
for(SelectionKey key: selector.selectedKeys()) { for(SelectionKey key: selector.selectedKeys()) {
if(key.isAcceptable()) { if(key.isAcceptable()) {
@ -194,11 +194,16 @@ public class Server implements Runnable {
} }
} }
long ctime = System.currentTimeMillis();
for(int i = clientList.size() - 1; i >= 0; i--) { for(int i = clientList.size() - 1; i >= 0; i--) {
ServerClient cli = clientList.get(i); ServerClient cli = clientList.get(i);
if(cli.shouldRemove()) if(cli.shouldRemove())
removeClient(cli); removeClient(cli);
else if(cli.hasTimedOut(ctime)) {
Log.info("Client %s has timed out!", cli.getUUIDString());
removeClient(cli);
}
} }
} }

View File

@ -32,6 +32,7 @@ public class ServerClient extends AbstractClient {
private long currentFileSize; private long currentFileSize;
private long currentFileExpectedSize; private long currentFileExpectedSize;
private boolean sendingFile; //!= receiving, which is handled by currentFile private boolean sendingFile; //!= receiving, which is handled by currentFile
private long lastDataTime;
ServerClient(SocketChannel s, Selector ss) { ServerClient(SocketChannel s, Selector ss) {
socket = s; socket = s;
@ -40,6 +41,8 @@ public class ServerClient extends AbstractClient {
try { try {
selKey = socket.register(selector, SelectionKey.OP_READ); selKey = socket.register(selector, SelectionKey.OP_READ);
} catch(ClosedChannelException ex) {} } catch(ClosedChannelException ex) {}
lastDataTime = System.currentTimeMillis();
} }
@Override @Override
@ -58,6 +61,10 @@ public class ServerClient extends AbstractClient {
return remove; return remove;
} }
public boolean hasTimedOut(long now) {
return now - lastDataTime >= Constants.CLIENT_TIMEOUT;
}
SocketChannel getChannel() { SocketChannel getChannel() {
return socket; return socket;
} }
@ -381,4 +388,13 @@ public class ServerClient extends AbstractClient {
} }
@Override
protected void onDataReceived() {
lastDataTime = System.currentTimeMillis();
}
public String getUUIDString() {
return (uuid == null) ? "[NOT IDENTIFIED YET]" : uuid.toString();
}
} }

View File

@ -116,7 +116,7 @@ webdisplays.server.unknowncmd=Unknown command.
webdisplays.server.error=Internal error. Check logs. webdisplays.server.error=Internal error. Check logs.
webdisplays.server.error2=Internal error %d. Check logs. webdisplays.server.error2=Internal error %d. Check logs.
webdisplays.server.argerror=Unrecognized argument. webdisplays.server.argerror=Unrecognized argument.
webdisplays.server.queryerr=Query error, check logs. webdisplays.server.queryerr=Query error, try "reconnect".
webdisplays.server.errowner=Only the owner can access this. webdisplays.server.errowner=Only the owner can access this.
webdisplays.server.timeout=Query timed out. Check logs. webdisplays.server.timeout=Query timed out. Check logs.
webdisplays.server.ownername=Owner name: %s webdisplays.server.ownername=Owner name: %s
@ -140,3 +140,4 @@ webdisplays.server.help.ls=Lists the files on this server
webdisplays.server.help.url=Copies a file URL into your clipboard webdisplays.server.help.url=Copies a file URL into your clipboard
webdisplays.server.help.upload=Opens the upload wizard webdisplays.server.help.upload=Opens the upload wizard
webdisplays.server.help.rm=Deletes a file webdisplays.server.help.rm=Deletes a file
webdisplays.server.help.reconnect=Reconnect to miniserv [DEBUG]