* 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
* Peripheral: OpenComputers interface
* Read config (see "Config elements" below)
* Miniserv timeout
### TODO
* French translations

View File

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

View File

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

View File

@ -50,7 +50,7 @@ public abstract class AbstractClient {
protected abstract void onWriteError();
public void readyRead(ByteBuffer bb) {
public final void readyRead(ByteBuffer bb) {
while(bb.remaining() > 0) {
if(packetReader.readFrom(bb)) { //End of packet
byte[] pkt = packetReader.getPacketData();
@ -79,14 +79,18 @@ public abstract class AbstractClient {
packetReader.reset();
}
}
onDataReceived();
}
public void readyWrite() throws Throwable {
public final void readyWrite() throws Throwable {
if(sendBuffer.remaining() > 0 || fillSendBuffer()) {
int sent = socket.write(sendBuffer);
if(sent < 0)
onWriteError();
else if(sent > 0)
onDataSent();
}
}
@ -115,7 +119,7 @@ public abstract class AbstractClient {
return pos > 0;
}
public void sendPacket(OutgoingPacket pkt) {
public final void sendPacket(OutgoingPacket pkt) {
synchronized(sendQueue) {
sendQueue.offer(pkt);
@ -138,15 +142,21 @@ public abstract class AbstractClient {
}
}
protected byte[] getCurrentPacketRawData() {
protected final byte[] getCurrentPacketRawData() {
return packetReader.getPacketData();
}
protected void clearSendQueue() {
protected final void clearSendQueue() {
synchronized(sendQueue) {
packetWriter.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_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 ClientTask currentTask;
private volatile boolean authenticated;
private long lastPingTime;
public SMessageMiniservConnect beginConnection() {
if(keyPair == null) {
@ -173,6 +174,7 @@ public class Client extends AbstractClient implements Runnable {
connPacket.writeLong(clientUUID.getMostSignificantBits());
connPacket.writeLong(clientUUID.getLeastSignificantBits());
sendPacket(connPacket);
lastPingTime = System.currentTimeMillis();
while(getRunning()) {
try {
@ -214,7 +216,8 @@ public class Client extends AbstractClient implements Runnable {
}
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())
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
@ -326,6 +337,10 @@ public class Client extends AbstractClient implements Runnable {
((ClientTaskDeleteFile) currentTask).onStatusPacket(dis.readByte());
}
@PacketHandler(PacketID.PING)
public void handlePing(DataInputStream dis) {
}
public void nextTask() {
if(currentTask != null)
currentTask.onFinished();
@ -365,4 +380,9 @@ public class Client extends AbstractClient implements Runnable {
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 {
selector.select();
selector.select(1000); //Allow the server to kick timed-out clients
for(SelectionKey key: selector.selectedKeys()) {
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--) {
ServerClient cli = clientList.get(i);
if(cli.shouldRemove())
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 currentFileExpectedSize;
private boolean sendingFile; //!= receiving, which is handled by currentFile
private long lastDataTime;
ServerClient(SocketChannel s, Selector ss) {
socket = s;
@ -40,6 +41,8 @@ public class ServerClient extends AbstractClient {
try {
selKey = socket.register(selector, SelectionKey.OP_READ);
} catch(ClosedChannelException ex) {}
lastDataTime = System.currentTimeMillis();
}
@Override
@ -58,6 +61,10 @@ public class ServerClient extends AbstractClient {
return remove;
}
public boolean hasTimedOut(long now) {
return now - lastDataTime >= Constants.CLIENT_TIMEOUT;
}
SocketChannel getChannel() {
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.error2=Internal error %d. Check logs.
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.timeout=Query timed out. Check logs.
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.upload=Opens the upload wizard
webdisplays.server.help.rm=Deletes a file
webdisplays.server.help.reconnect=Reconnect to miniserv [DEBUG]