Files
rosetta-wss/src/main/java/io/orprotocol/Server.java
2026-02-02 05:30:38 +02:00

139 lines
5.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package io.orprotocol;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import io.orprotocol.client.Client;
import io.orprotocol.packet.Packet;
import io.orprotocol.packet.PacketExecutor;
import io.orprotocol.packet.PacketManager;
public class Server extends WebSocketServer {
private PacketManager packetManager;
private Settings settings;
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private Object attachment;
public Server(Settings settings, PacketManager packetManager, Object attachment) {
super(new InetSocketAddress(settings.port));
this.settings = settings;
this.packetManager = packetManager;
this.attachment = attachment;
}
@Override
public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
}
@Override
public void onError(WebSocket arg0, Exception arg1) {
}
@Override
public void onMessage(WebSocket socket, String message) {
/**
* Обновляем время последнего полученного heartbeat.
* Так как клиент отпраивл нам пакет, он живой.
*/
Client client = socket.getAttachment();
client.updateHeartbeat();
}
@Override
public void onMessage(WebSocket socket, ByteBuffer byteBuffer) {
Client client = socket.getAttachment();
byte[] bytes = byteBuffer.array();
Stream stream = new Stream(bytes);
int packetId = stream.readInt16();
/**
* Обновляем время последнего полученного heartbeat.
* Так как клиент отпраивл нам пакет, он живой.
*/
client.updateHeartbeat();
if(!this.packetManager.hasPacketSupported(packetId)){
/**
* Если пакет не поддерживается, отключаем клиента с соответствующим кодом ошибки.
*/
client.disconnect(ServerFailures.UNSUPPORTED_PACKET);
return;
}
if(!this.packetManager.hasExecutorDelegated(packetId)){
/**
* Если для пакета не назначен обработчик, отключаем клиента с соответствующим кодом ошибки.
*/
client.disconnect(ServerFailures.UNSUPPORTED_PACKET);
return;
}
Class<? extends Packet> packetClass = this.packetManager.getPacketClass(packetId);
try {
Packet packet = packetClass.getConstructor().newInstance();
packet.packetId = packetId;
/**
* Читаем данные пакета из потока.
*/
packet.read(stream);
/**
* Получаем обработчик пакета и вызываем его метод обработки.
*/
Class<? extends PacketExecutor> executorClass = this.packetManager.getExecutors().get(packetId);
PacketExecutor executor = executorClass.getConstructor().newInstance();
executor.settings = this.settings;
executor.attachment = this.attachment;
executor.onPacketReceived(packet, client);
} catch (Exception e) {
System.out.println("Error while processing packet " + packetClass.getName());
System.out.println(e.getStackTrace());
}
}
@Override
public void onOpen(WebSocket socket, ClientHandshake arg1) {
/**
* Создаем нового клиента при открытии соединения.
* Передаем интервал heartbeat из настроек сервера.
* Если клиент не отправляет heartbeat в указанный интервал, его можно отключить.
*/
Client client = new Client(socket, this.settings.heartbeatInterval);
socket.setAttachment(client);
}
@Override
public void onStart() {
/**
* Настраиваем планировщик для проверки активности клиентов.
*/
this.inactivityShedulerTweaker();
int port = this.getPort();
System.out.println("\u001B[32mServer started at x.x.x.x:" + port + "\u001B[0m");
}
/**
* Планировщик для проверки активности клиентов.
* Если планировщик обнаруживает неактивного клиента, он отключает его с соответствующим кодом ошибки.
*/
public void inactivityShedulerTweaker() {
this.scheduler.scheduleAtFixedRate(() -> {
for(WebSocket socket : this.getConnections()) {
Client client = socket.getAttachment();
if(!client.isAlive()) {
client.disconnect(ServerFailures.INACTIVITY_TIMEOUT);
}
}
}, this.settings.heartbeatInterval, this.settings.heartbeatInterval, TimeUnit.MILLISECONDS);
}
}