Базовый SFU SDK для g365sfu
This commit is contained in:
@@ -17,6 +17,7 @@ import im.rosetta.executors.Executor21GroupLeave;
|
||||
import im.rosetta.executors.Executor22GroupBan;
|
||||
import im.rosetta.executors.Executor24DeviceResolve;
|
||||
import im.rosetta.executors.Executor25Sync;
|
||||
import im.rosetta.executors.Executor26Signal;
|
||||
import im.rosetta.executors.Executor3Search;
|
||||
import im.rosetta.executors.Executor4OnlineState;
|
||||
import im.rosetta.executors.Executor6Message;
|
||||
@@ -54,6 +55,8 @@ import im.rosetta.packet.Packet7Read;
|
||||
import im.rosetta.packet.Packet8Delivery;
|
||||
import im.rosetta.packet.Packet9DeviceNew;
|
||||
import im.rosetta.service.services.BufferCleanupService;
|
||||
import im.rosetta.service.services.ForwardUnitService;
|
||||
import io.g365sfu.SFU;
|
||||
import io.orprotocol.Server;
|
||||
import io.orprotocol.Settings;
|
||||
import io.orprotocol.packet.PacketManager;
|
||||
@@ -75,6 +78,7 @@ public class Boot {
|
||||
private ClientManager clientManager;
|
||||
private OnlineManager onlineManager;
|
||||
private BufferCleanupService bufferCleanupService;
|
||||
private ForwardUnitService forwardUnitService;
|
||||
|
||||
/**
|
||||
* Конструктор по умолчанию, использует порт 3000 для сервера
|
||||
@@ -106,6 +110,7 @@ public class Boot {
|
||||
int cleanupEveryDays = System.getenv("BUFFER_CLEANUP_DAYS") != null ?
|
||||
Integer.parseInt(System.getenv("BUFFER_CLEANUP_DAYS")) : 7;
|
||||
this.bufferCleanupService = new BufferCleanupService(cleanupEveryDays, this.logger);
|
||||
this.forwardUnitService = new ForwardUnitService(this.logger);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +157,8 @@ public class Boot {
|
||||
this.registerAllEvents();
|
||||
this.printBootMessage();
|
||||
this.bufferCleanupService.start();
|
||||
return this;
|
||||
this.forwardUnitService.connectToAllSFUServers();
|
||||
return this;
|
||||
}catch(Exception e){
|
||||
this.logger.error(Color.RED + "Booting error, stack trace:");
|
||||
e.printStackTrace();
|
||||
@@ -217,6 +223,7 @@ public class Boot {
|
||||
this.packetManager.registerExecutor(22, new Executor22GroupBan());
|
||||
this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager, this.packetManager));
|
||||
this.packetManager.registerExecutor(25, new Executor25Sync(this.packetManager));
|
||||
this.packetManager.registerExecutor(26, new Executor26Signal(this.clientManager));
|
||||
}
|
||||
|
||||
private void printBootMessage() {
|
||||
|
||||
39
src/main/java/im/rosetta/executors/Executor26Signal.java
Normal file
39
src/main/java/im/rosetta/executors/Executor26Signal.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package im.rosetta.executors;
|
||||
|
||||
import im.rosetta.client.ClientManager;
|
||||
import im.rosetta.client.tags.ECIAuthentificate;
|
||||
import im.rosetta.packet.Packet26Signal;
|
||||
import io.orprotocol.ProtocolException;
|
||||
import io.orprotocol.client.Client;
|
||||
import io.orprotocol.packet.PacketExecutor;
|
||||
|
||||
public class Executor26Signal extends PacketExecutor<Packet26Signal> {
|
||||
|
||||
public ClientManager clientManager;
|
||||
|
||||
public Executor26Signal(ClientManager clientManager) {
|
||||
this.clientManager = clientManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceived(Packet26Signal packet, Client client) throws Exception, ProtocolException {
|
||||
ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class);
|
||||
if (eciAuthentificate == null || !eciAuthentificate.hasAuthorized()) {
|
||||
/**
|
||||
* Если клиент не авторизован, то мы не будем обрабатывать его сигналы на анициализацию звонка
|
||||
* и просто отключим его от сервера.
|
||||
*/
|
||||
client.disconnect();
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* TODO: Проверка на существование получателя
|
||||
*/
|
||||
this.clientManager.sendPacketToAuthorizedPK(packet.getDst(), packet);
|
||||
/**
|
||||
* TODO: Высокоприоритетный пуш для сигналов звонков, чтобы мобильные устройства могли показать
|
||||
* интерфейс входящего звонка, даже если приложение находится в фоне
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,25 +5,21 @@ package im.rosetta.packet.runtime;
|
||||
*/
|
||||
public enum NetworkSignalType {
|
||||
/**
|
||||
* CALL - сигнал для совершения звонка, инициирует процесс звонка
|
||||
* Сигнал для совершения звонка, инициирует процесс звонка
|
||||
*/
|
||||
CALL(0),
|
||||
/**
|
||||
* KEY_EXCHANGE - сигнал для обмена ключами, используется для обмена DH ключами между участниками звонка
|
||||
* Сигнал для обмена ключами, используется для обмена DH ключами между участниками звонка
|
||||
*/
|
||||
KEY_EXCHANGE(1),
|
||||
/**
|
||||
* ICE_CANDIDATE - сигнал для обмена ICE кандидатами, используется для обмена сетевыми кандидатами между участниками звонка
|
||||
* Сигнал для активного звонка, указывает на то, что звонок активен и участники могут обмениваться данными
|
||||
*/
|
||||
ICE_CONFIG(2),
|
||||
ACTIVE_CALL(2),
|
||||
/**
|
||||
* ACTIVE_CALL - сигнал для активного звонка, указывает на то, что звонок активен и участники могут обмениваться данными
|
||||
* Сигнал для завершения звонка, указывает на то, что звонок завершен и участники должны прекратить обмен данными
|
||||
*/
|
||||
ACTIVE_CALL(3),
|
||||
/**
|
||||
* END_CALL - сигнал для завершения звонка, указывает на то, что звонок завершен и участники должны прекратить обмен данными
|
||||
*/
|
||||
END_CALL(4);
|
||||
END_CALL(3);
|
||||
|
||||
private final int code;
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package im.rosetta.service.services;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import im.rosetta.logger.Logger;
|
||||
import im.rosetta.logger.enums.Color;
|
||||
import io.g365sfu.SFU;
|
||||
|
||||
/**
|
||||
* Это сервис который взаимодействуют с SFU серверами для организации звонков между пользователями.
|
||||
*/
|
||||
public class ForwardUnitService {
|
||||
|
||||
private Logger logger;
|
||||
private Set<SFU> sfuConnections = new HashSet<>();
|
||||
|
||||
public ForwardUnitService(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализирует соединения к SFU серверам для звонков.
|
||||
* Ожидается, что адреса SFU серверов и секретные ключи для них будут переданы через переменную окружения SFU_SERVERS в формате "address1@secretKey1,address2@secretKey2,...".
|
||||
* Для каждого сервера будет предпринята попытка установить соединение и выполнить рукопожатие.
|
||||
* Если соединение не может быть установлено или рукопожатие не удается,
|
||||
* будет выведено сообщение об ошибке в лог, но процесс продолжится для остальных серверов.
|
||||
* Успешные подключения будут сохранены в наборе sfuConnections для дальнейшего использования
|
||||
*/
|
||||
public void connectToAllSFUServers() {
|
||||
String sfuServersEnv = System.getenv("SFU_SERVERS");
|
||||
if(sfuServersEnv == null || sfuServersEnv.isEmpty()) {
|
||||
this.logger.info(Color.YELLOW + "No SFU servers configured, skipping SFU connections boot");
|
||||
return;
|
||||
}
|
||||
String[] sfuServers = sfuServersEnv.split(",");
|
||||
for(String sfuServer : sfuServers) {
|
||||
String[] parts = sfuServer.split("@");
|
||||
if(parts.length != 2) {
|
||||
this.logger.error(Color.RED + "Invalid SFU server configuration: " + sfuServer);
|
||||
continue;
|
||||
}
|
||||
String address = parts[0];
|
||||
String secretKey = parts[1];
|
||||
try {
|
||||
SFU connection = new SFU(address, secretKey);
|
||||
connection.connect();
|
||||
this.sfuConnections.add(connection);
|
||||
this.logger.info(Color.GREEN + "Successfully connected to SFU server: " + address);
|
||||
} catch (Exception e) {
|
||||
this.logger.error(Color.RED + "Failed to connect to SFU server: " + address + ", error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user