dev #5

Merged
Royce59 merged 7 commits from dev into main 2026-02-21 18:12:43 +00:00
6 changed files with 68 additions and 11 deletions

View File

@@ -203,7 +203,7 @@ public class Boot {
this.packetManager.registerExecutor(20, new Executor20GroupJoin());
this.packetManager.registerExecutor(21, new Executor21GroupLeave());
this.packetManager.registerExecutor(22, new Executor22GroupBan());
this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager));
this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager, this.packetManager));
this.packetManager.registerExecutor(25, new Executor25Sync(this.packetManager));
}

View File

@@ -41,7 +41,7 @@ public class User extends CreateUpdateEntity {
private String publicKey;
@Convert(converter = StringListConverter.class)
@Column(name = "notificationsTokens", nullable = false)
@Column(name = "notificationsTokens", nullable = false, columnDefinition = "TEXT")
private List<String> notificationsTokens = new ArrayList<>();

View File

@@ -7,6 +7,7 @@ import im.rosetta.client.ClientManager;
import im.rosetta.client.tags.ECIAuthentificate;
import im.rosetta.client.tags.ECIDevice;
import im.rosetta.database.entity.Device;
import im.rosetta.database.repository.BufferRepository;
import im.rosetta.database.repository.DeviceRepository;
import im.rosetta.event.EventManager;
import im.rosetta.event.events.handshake.HandshakeCompletedEvent;
@@ -15,10 +16,11 @@ import im.rosetta.packet.Packet24DeviceResolve;
import im.rosetta.packet.runtime.DeviceSolution;
import im.rosetta.packet.runtime.HandshakeStage;
import im.rosetta.service.dispatch.DeviceDispatcher;
import im.rosetta.service.services.BufferService;
import io.orprotocol.ProtocolException;
import io.orprotocol.client.Client;
import io.orprotocol.packet.PacketExecutor;
import io.orprotocol.packet.PacketManager;
public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolve> {
@@ -26,11 +28,14 @@ public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolv
private final EventManager eventManager;
private final DeviceRepository deviceRepository = new DeviceRepository();
private final DeviceDispatcher deviceDispatcher;
private final BufferRepository bufferRepository = new BufferRepository();
private final BufferService bufferService;
public Executor24DeviceResolve(ClientManager clientManager, EventManager eventManager) {
public Executor24DeviceResolve(ClientManager clientManager, EventManager eventManager, PacketManager packetManager) {
this.clientManager = clientManager;
this.eventManager = eventManager;
this.deviceDispatcher = new DeviceDispatcher(clientManager);
this.bufferService = new BufferService(this.bufferRepository, packetManager);
}
@Override
@@ -68,15 +73,18 @@ public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolv
device.setPublicKey(eciAuthentificate.getPublicKey());
device.setDeviceOs(deviceTag.getDeviceOs());
device.setDeviceName(deviceTag.getDeviceName());
/**
* TODO: Здесь можно реализовать отключение синхронизации,
* например если у пользователя отключена синхронизация, то при разрешении нового устройства
* можно устанавливать leaveTime как текущее время, тогда сообщения новому устройству не загрузятся.
* Если установить leaveTime в 0, то синхронизируются все сообщения которые есть на сервере
*/
device.setSyncTime(0L);
this.deviceRepository.save(device);
/**
* Сбрасываем клиенту все подтверждения устройств, чтобы исключить спам запросами,
* а так же исправить баг, когда при подключении первого устройства показывалось уведомление
* о новом входе.
*
* 9 ID пакета - Packet9DeviceNew
*/
this.bufferService.deletePacketsFromBuffer(eciAuthentificate.getPublicKey(), 9, 0);
/**
* Устанавливаем пользователю успешный хэндшейк
*/
@@ -118,6 +126,14 @@ public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolv
* о присоединении нового устройства)
*/
this.deviceDispatcher.sendDevices(eciAuthentificate.getPublicKey());
/**
* Сбрасываем клиенту все подтверждения устройств, чтобы исключить спам запросами,
* а так же исправить баг, когда при подключении первого устройства показывалось уведомление
* о новом входе.
*
* 9 ID пакета - Packet9DeviceNew
*/
this.bufferService.deletePacketsFromBuffer(eciAuthentificate.getPublicKey(), 9, 0);
break;
}
}

View File

@@ -117,6 +117,17 @@ public class BufferService extends Service<BufferRepository> {
*/
public void deletePacketsFromBuffer(String to, Packet packet, long fromTimestampMs) {
int packetId = this.packetManager.getPacketIdByClass(packet.getClass());
this.deletePacketsFromBuffer(to, packetId, fromTimestampMs);
}
/**
* Удаляет из буфера все пакеты для определенного клиента с публичным ключом to, которые были добавлены
* в буфер после fromTimestampMs и имееют такой же ID пакета как и переданный
* @param to публичный ключ получателя пакета
* @param packetId ID пакета, который нужно удалить
* @param fromTimestampMs метка времени в миллисекундах, после которой были добавлены пакеты, которые нужно удалить
*/
public void deletePacketsFromBuffer(String to, int packetId, long fromTimestampMs){
String hql = "DELETE FROM Buffer WHERE to = :to AND packetId = :packetId AND timestamp > :timestamp";
HashMap<String, Object> parameters = new HashMap<>();
parameters.put("to", to);

View File

@@ -155,13 +155,23 @@ public class Server extends WebSocketServer {
}
@Override
public void onOpen(WebSocket socket, ClientHandshake arg1) {
public void onOpen(WebSocket socket, ClientHandshake handshake) {
/**
* Создаем нового клиента при открытии соединения.
* Передаем интервал heartbeat из настроек сервера.
* Если клиент не отправляет heartbeat в указанный интервал, его можно отключить.
*/
Client client = new Client(socket, this.settings.heartbeatInterval, this);
String ipAddress = handshake.getFieldValue("X-Forwarded-For");
if (ipAddress == null || ipAddress.isEmpty()) {
ipAddress = socket.getRemoteSocketAddress().getAddress().getHostAddress();
} else {
/**
* Берем первый IP адрес из списка разделенного запятой
*/
ipAddress = ipAddress.split(",")[0].trim();
}
client.setIpAddress(ipAddress);
socket.setAttachment(client);
if(this.listener == null){
return;

View File

@@ -29,6 +29,10 @@ public class Client {
* Интервал отправки heartbeat пакетов в миллисекундах.
*/
public long heartbeatInterval = 0;
/**
* IP-адрес клиента
*/
private String ipAddress;
/**
* Время последнего полученного heartbeat в миллисекундах.
*/
@@ -71,6 +75,22 @@ public class Client {
this.lastHeartbeatTime = System.currentTimeMillis();
}
/**
* Получает IP адрес клиента
* @return адрес
*/
public String getIpAddress() {
return this.ipAddress;
}
/**
* Устанавливает IP адрес клиента
* @param ipAddress адрес
*/
public void setIpAddress(String ipAddress){
this.ipAddress = ipAddress;
}
/**
* Получает уникальный идентификатор клиента.
* @return Идентификатор клиента.