diff --git a/src/main/java/com/rosetta/im/Boot.java b/src/main/java/com/rosetta/im/Boot.java index 0f1c21b..0ef4cd0 100644 --- a/src/main/java/com/rosetta/im/Boot.java +++ b/src/main/java/com/rosetta/im/Boot.java @@ -3,9 +3,11 @@ package com.rosetta.im; import com.rosetta.im.client.ClientManager; import com.rosetta.im.client.OnlineManager; import com.rosetta.im.config.Configuration; +import com.rosetta.im.config.ServerConfiguration; import com.rosetta.im.event.EventManager; import com.rosetta.im.executors.Executor0Handshake; import com.rosetta.im.executors.Executor11Typeing; +import com.rosetta.im.executors.Executor15RequestTransport; import com.rosetta.im.executors.Executor1UserInfo; import com.rosetta.im.executors.Executor24DeviceResolve; import com.rosetta.im.executors.Executor3Search; @@ -22,6 +24,7 @@ import com.rosetta.im.logger.enums.Color; import com.rosetta.im.logger.enums.LogLevel; import com.rosetta.im.packet.Packet0Handshake; import com.rosetta.im.packet.Packet11Typeing; +import com.rosetta.im.packet.Packet15RequestTransport; import com.rosetta.im.packet.Packet1UserInfo; import com.rosetta.im.packet.Packet23DeviceList; import com.rosetta.im.packet.Packet24DeviceResolve; @@ -55,6 +58,7 @@ public class Boot { private ClientManager clientManager; private OnlineManager onlineManager; private Configuration configuration; + private ServerConfiguration serverConfiguration; public Boot() { this.packetManager = new PacketManager(); @@ -108,7 +112,7 @@ public class Boot { */ public Boot bootstrap() { try{ - this.configuration.loadConfiguration(); + this.serverConfiguration = this.configuration.loadConfiguration(); this.server.start(); this.registerAllPackets(); this.registerAllExecutors(); @@ -116,7 +120,7 @@ public class Boot { this.printBootMessage(); return this; }catch(Exception e){ - this.logger.error("Booting error, stack trace:"); + this.logger.error(Color.RED + "Booting error, stack trace:"); e.printStackTrace(); return null; } @@ -142,6 +146,7 @@ public class Boot { this.packetManager.registerPacket(8, Packet8Delivery.class); this.packetManager.registerPacket(9, Packet9DeviceNew.class); this.packetManager.registerPacket(11, Packet11Typeing.class); + this.packetManager.registerPacket(15, Packet15RequestTransport.class); this.packetManager.registerPacket(23, Packet23DeviceList.class); this.packetManager.registerPacket(24, Packet24DeviceResolve.class); @@ -155,6 +160,7 @@ public class Boot { this.packetManager.registerExecutor(6, new Executor6Message(this.clientManager, this.packetManager)); this.packetManager.registerExecutor(7, new Executor7Read(this.clientManager, this.packetManager)); this.packetManager.registerExecutor(11, new Executor11Typeing(this.clientManager, this.packetManager)); + this.packetManager.registerExecutor(15, new Executor15RequestTransport(this.serverConfiguration)); this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager)); } diff --git a/src/main/java/com/rosetta/im/config/ServerConfiguration.java b/src/main/java/com/rosetta/im/config/ServerConfiguration.java index de36447..d400017 100644 --- a/src/main/java/com/rosetta/im/config/ServerConfiguration.java +++ b/src/main/java/com/rosetta/im/config/ServerConfiguration.java @@ -9,7 +9,17 @@ public class ServerConfiguration { public DatabaseConfiguration database; - public List cdn_servers; + public List transport_servers; + + public List update_servers; + + public List getUpdateServers() { + return update_servers; + } + + public void setUpdateServers(List update_servers) { + this.update_servers = update_servers; + } public DatabaseConfiguration getDatabase() { return database; @@ -19,12 +29,12 @@ public class ServerConfiguration { this.database = database; } - public List getCdnServers() { - return cdn_servers; + public List getTransportServers() { + return transport_servers; } - public void setCdnServers(List cdn_servers) { - this.cdn_servers = cdn_servers; + public void setTransportServers(List transport_servers) { + this.transport_servers = transport_servers; } diff --git a/src/main/java/com/rosetta/im/executors/Executor15RequestTransport.java b/src/main/java/com/rosetta/im/executors/Executor15RequestTransport.java new file mode 100644 index 0000000..d530b92 --- /dev/null +++ b/src/main/java/com/rosetta/im/executors/Executor15RequestTransport.java @@ -0,0 +1,48 @@ +package com.rosetta.im.executors; + +import java.util.List; + +import com.rosetta.im.Failures; +import com.rosetta.im.client.tags.ECIAuthentificate; +import com.rosetta.im.config.ServerConfiguration; +import com.rosetta.im.packet.Packet15RequestTransport; +import com.rosetta.im.util.RandomUtil; + +import io.orprotocol.ProtocolException; +import io.orprotocol.client.Client; +import io.orprotocol.packet.PacketExecutor; + +public class Executor15RequestTransport extends PacketExecutor { + + private ServerConfiguration serverConfiguration; + + public Executor15RequestTransport(ServerConfiguration serverConfiguration){ + this.serverConfiguration = serverConfiguration; + } + + @Override + public void onPacketReceived(Packet15RequestTransport packet, Client client) throws Exception, ProtocolException { + ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class); + if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()){ + /** + * Пользователь не авторизован, но запросил транспортный сервер - это неправильное поведение + */ + client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED); + return; + } + /** + * Если пользователь авторизован, выбираем случайный транспортный сервер и + * заполняем им пакет + * + * TODO: Логика проверки на доступность (health) + */ + List cdnServers = this.serverConfiguration.getTransportServers(); + String selectedServer = cdnServers.get(RandomUtil.randomBetween(0, cdnServers.size() - 1)); + packet.setTransportServer(selectedServer); + /** + * Сервер выбран, отправляем готовый пакет клиенту + */ + client.send(packet); + } + +} diff --git a/src/main/java/com/rosetta/im/packet/Packet15RequestTransport.java b/src/main/java/com/rosetta/im/packet/Packet15RequestTransport.java new file mode 100644 index 0000000..a7ef414 --- /dev/null +++ b/src/main/java/com/rosetta/im/packet/Packet15RequestTransport.java @@ -0,0 +1,44 @@ +package com.rosetta.im.packet; + +import io.orprotocol.Stream; +import io.orprotocol.packet.Packet; + +/** + * Пакет отправляется клиентом для запроса транспортного сервера, строка в этот момент клиентом + * не заполняется, а уже обратно сервер заполняет строку и записывает туда транспортный сервер + * чтобы клиент мог отправлять вложения на него + */ +public class Packet15RequestTransport extends Packet { + + private String transportServer; + + @Override + public void read(Stream stream) { + this.transportServer = stream.readString(); + } + + @Override + public Stream write() { + Stream stream = new Stream(); + stream.writeInt16(this.packetId); + stream.writeString(this.transportServer); + return stream; + } + + /** + * Получить транспортный сервер + * @return транспортный сервер + */ + public String getTransportServer() { + return transportServer; + } + + /** + * Установить транспортный сервер + * @param transportServer транспортный сервер + */ + public void setTransportServer(String transportServer) { + this.transportServer = transportServer; + } + +} diff --git a/src/main/java/com/rosetta/im/util/RandomUtil.java b/src/main/java/com/rosetta/im/util/RandomUtil.java new file mode 100644 index 0000000..b1d8764 --- /dev/null +++ b/src/main/java/com/rosetta/im/util/RandomUtil.java @@ -0,0 +1,18 @@ +package com.rosetta.im.util; + +import java.util.Random; + +public class RandomUtil { + + /** + * Генерирует случайное число в диапазоне от min до max + * @param min минимальное число + * @param max максимальное число + * @return случайное число в диапазоне между min и max + */ + public static int randomBetween(int min, int max) { + Random random = new Random(); + return random.nextInt((max - min) + 1) + min; + } + +}