From 312cc5df0fa5360455d64029d70b875dd6ad8353 Mon Sep 17 00:00:00 2001 From: RoyceDa Date: Sat, 14 Mar 2026 22:57:59 +0200 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=20ICE=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=20(TURN)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 8 ++- .../executors/Executor28IceServers.java | 39 +++++++++++++ .../im/rosetta/packet/Packet28IceServers.java | 56 +++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/main/java/im/rosetta/executors/Executor28IceServers.java create mode 100644 src/main/java/im/rosetta/packet/Packet28IceServers.java diff --git a/.env b/.env index c21b809..251f355 100644 --- a/.env +++ b/.env @@ -8,9 +8,9 @@ PORT=3000 # Порт, на котором будет работать серве # Список серверов CDN и SDU. Разделяются запятой если их несколько # Без пробелов -CDN_SERVERS=http://10.211.55.2:7789 +CDN_SERVERS=http://192.168.6.82:7789 #SDU - Server Delivery Updates -SDU_SERVERS=http://10.211.55.2:7777 +SDU_SERVERS=http://192.168.6.82:7777 #Firebase Credentials FIREBASE_CREDENTIALS_PATH=serviceAccount.json @@ -21,3 +21,7 @@ BUFFER_CLEANUP_DAYS=7 #SFU Сервера SFU_SERVERS=127.0.0.1:1001@SFU_TEST_SECRET +#TURN Сервера (должны поддерживать TCP и UDP протоколы) +# Формат: host:port@username:password через запятую если их несколько, без пробелов +TURN_SERVERS=192.168.6.82:3478@user:pass + diff --git a/src/main/java/im/rosetta/executors/Executor28IceServers.java b/src/main/java/im/rosetta/executors/Executor28IceServers.java new file mode 100644 index 0000000..e9007b7 --- /dev/null +++ b/src/main/java/im/rosetta/executors/Executor28IceServers.java @@ -0,0 +1,39 @@ +package im.rosetta.executors; + +import java.util.ArrayList; + +import im.rosetta.Failures; +import im.rosetta.client.tags.ECIAuthentificate; +import im.rosetta.packet.Packet28IceServers; +import im.rosetta.service.services.ForwardUnitService; +import io.orprotocol.ProtocolException; +import io.orprotocol.client.Client; +import io.orprotocol.packet.PacketExecutor; + +public class Executor28IceServers extends PacketExecutor { + + private ForwardUnitService fus; + + public Executor28IceServers(ForwardUnitService fus) { + this.fus = fus; + } + + @Override + public void onPacketReceived(Packet28IceServers packet, Client client) throws Exception, ProtocolException { + ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class); + if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()) { + /** + * Если клиент не авторизован, то мы не будем обрабатывать его запрос на получение ICE серверов + * и просто отключим его от сервера. + */ + client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED); + return; + } + /** + * Берем TURN сервера и отправляем их клиенту + */ + packet.setIceServers(new ArrayList<>(this.fus.getTurnServers())); + client.send(packet); + } + +} diff --git a/src/main/java/im/rosetta/packet/Packet28IceServers.java b/src/main/java/im/rosetta/packet/Packet28IceServers.java new file mode 100644 index 0000000..7562e6a --- /dev/null +++ b/src/main/java/im/rosetta/packet/Packet28IceServers.java @@ -0,0 +1,56 @@ +package im.rosetta.packet; + +import java.util.ArrayList; +import java.util.List; + +import io.g365sfu.webrtc.RTCIceServer; +import io.orprotocol.Stream; +import io.orprotocol.packet.Packet; + +public class Packet28IceServers extends Packet { + + private List iceServers; + + @Override + public void read(Stream stream) { + int count = stream.readInt16(); + this.iceServers = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String url = stream.readString(); + String username = stream.readString(); + String credential = stream.readString(); + RTCIceServer iceServer = new RTCIceServer(url, username, credential); + iceServers.add(iceServer); + } + } + + @Override + public Stream write() { + Stream stream = new Stream(); + stream.writeInt16(this.packetId); + stream.writeInt16(iceServers.size()); + for (RTCIceServer iceServer : iceServers) { + stream.writeString(iceServer.getUrl()); + stream.writeString(iceServer.getUsername()); + stream.writeString(iceServer.getCredential()); + } + return stream; + } + + /** + * Получить список серверов ICE, которые могут быть использованы для обмена кандидатами между участниками звонка через сервер SFU. + * @return список серверов ICE, которые могут быть использованы для обмена кандидатами между участниками звонка через сервер SFU. + */ + public List getIceServers() { + return iceServers; + } + + /** + * Установить список серверов ICE, которые могут быть использованы для обмена кандидатами между участниками звонка через сервер SFU. + * @param iceServers список серверов ICE, которые могут быть использованы для обмена кандидатами между участниками звонка через сервер SFU. + */ + public void setIceServers(List iceServers) { + this.iceServers = iceServers; + } + +}