diff --git a/src/main/java/io/orprotocol/ProtocolException.java b/src/main/java/io/orprotocol/ProtocolException.java new file mode 100644 index 0000000..5ec291d --- /dev/null +++ b/src/main/java/io/orprotocol/ProtocolException.java @@ -0,0 +1,9 @@ +package io.orprotocol; + +public class ProtocolException extends Exception { + + public ProtocolException(String message) { + super(message); + } + +} diff --git a/src/main/java/io/orprotocol/Server.java b/src/main/java/io/orprotocol/Server.java index 26dde38..51ed4bd 100644 --- a/src/main/java/io/orprotocol/Server.java +++ b/src/main/java/io/orprotocol/Server.java @@ -48,6 +48,14 @@ public class Server extends WebSocketServer { this.context = context; } + /** + * Конструктор сервера с объектом прикрепления и слушателем событий сервера + * @param settings базовые настройки серверера + * @param packetManager менеджер пакетов (обработчиков и зарегистрированных пакетов) + * @param context вложение которое будет передаваться всем серрверным обработчикам пакетов, + * @param listener слушатель событий сервера + * может быть использовано для передачи контекста приложения + */ public Server(Settings settings, PacketManager packetManager, Context context, ServerListener listener) { super(new InetSocketAddress(settings.port)); this.settings = settings; @@ -114,8 +122,8 @@ public class Server extends WebSocketServer { client.disconnect(ServerFailures.UNSUPPORTED_PACKET); return; } - Class packetClass = this.packetManager.getPacketClass(packetId); + Class packetClass = this.packetManager.getPacketClass(packetId); try { Packet packet = packetClass.getConstructor().newInstance(); packet.packetId = packetId; @@ -150,7 +158,7 @@ public class Server extends WebSocketServer { * Передаем интервал heartbeat из настроек сервера. * Если клиент не отправляет heartbeat в указанный интервал, его можно отключить. */ - Client client = new Client(socket, this.settings.heartbeatInterval); + Client client = new Client(socket, this.settings.heartbeatInterval, this.packetManager); socket.setAttachment(client); if(this.listener == null){ return; diff --git a/src/main/java/io/orprotocol/client/Client.java b/src/main/java/io/orprotocol/client/Client.java index 3233053..f995339 100644 --- a/src/main/java/io/orprotocol/client/Client.java +++ b/src/main/java/io/orprotocol/client/Client.java @@ -6,7 +6,11 @@ import java.util.Set; import org.java_websocket.WebSocket; import io.orprotocol.BaseFailures; +import io.orprotocol.ProtocolException; import io.orprotocol.ServerFailures; +import io.orprotocol.Stream; +import io.orprotocol.packet.Packet; +import io.orprotocol.packet.PacketManager; import io.orprotocol.util.StringUtil; /** @@ -29,18 +33,21 @@ public class Client { */ private volatile long lastHeartbeatTime; + private PacketManager packetManager; + /** * Создает нового клиента с указанным сокетом. * Этот метод используется внутри протокола для управления подключениями клиентов. * @param socket Веб-сокет клиента. * */ - public Client(WebSocket socket, long heartbeatInterval) { + public Client(WebSocket socket, long heartbeatInterval, PacketManager packetManager) { this.socket = socket; this.clientId = StringUtil.randomString(32); this.eciTags = new HashSet(); this.heartbeatInterval = heartbeatInterval; this.lastHeartbeatTime = System.currentTimeMillis(); + this.packetManager = new PacketManager(); } /** @@ -160,4 +167,21 @@ public class Client { this.disconnect(ServerFailures.UNKNOWN_FAILURE); } + /** + * Отправляет пакет клиенту. + * @param packet Пакет для отправки. + */ + public void send(Packet packet) throws ProtocolException { + Integer packetId = this.packetManager.getPacketIdByClass(packet.getClass()); + if(packetId == null) { + throw new ProtocolException("Unknown packet class: " + packet.getClass().getName()); + } + packet.packetId = packetId; + /** + * Записываем пакет в поток и отправляем его через сокет. + */ + Stream stream = packet.write(); + this.socket.send(stream.getBuffer()); + } + } diff --git a/src/main/java/io/orprotocol/packet/Packet.java b/src/main/java/io/orprotocol/packet/Packet.java index 3eb26f9..f27431b 100644 --- a/src/main/java/io/orprotocol/packet/Packet.java +++ b/src/main/java/io/orprotocol/packet/Packet.java @@ -10,10 +10,6 @@ public abstract class Packet { public int packetId; public PacketManager packetManager; - public Packet() { - - } - /** * Записывает данные пакета в поток. Исползуется при отправке * diff --git a/src/main/java/io/orprotocol/packet/PacketExecutor.java b/src/main/java/io/orprotocol/packet/PacketExecutor.java index 373dec0..d2ad093 100644 --- a/src/main/java/io/orprotocol/packet/PacketExecutor.java +++ b/src/main/java/io/orprotocol/packet/PacketExecutor.java @@ -1,6 +1,7 @@ package io.orprotocol.packet; import io.orprotocol.Context; +import io.orprotocol.ProtocolException; import io.orprotocol.Settings; import io.orprotocol.client.Client; @@ -32,5 +33,5 @@ public abstract class PacketExecutor { * @param packet Пакет, полученный от клиента. * @param client Клиент, отправивший пакет. */ - public abstract void onPacketReceived(Packet packet, Client client); + public abstract void onPacketReceived(Packet packet, Client client) throws Exception, ProtocolException; } diff --git a/src/main/java/io/orprotocol/packet/PacketManager.java b/src/main/java/io/orprotocol/packet/PacketManager.java index 6ba9ff4..a193654 100644 --- a/src/main/java/io/orprotocol/packet/PacketManager.java +++ b/src/main/java/io/orprotocol/packet/PacketManager.java @@ -42,10 +42,19 @@ public class PacketManager { return this.packets.containsKey(packetId); } + /** + * Возвращает зарегистрированные исполнители пакетов. + * @return Хэш-карта зарегистрированных исполнителей пакетов. + */ public HashMap> getExecutors() { return this.executors; } + /** + * Получает пакет ID по экземпляру класса + * @param packetClass Класс пакета + * @return ID пакета + */ public Integer getPacketIdByClass(Class packetClass) { for (var entry : this.packets.entrySet()) { if (entry.getValue().equals(packetClass)) {