Сообщения, доставка сообщений, фикс хэндшейков, буферная зона (для синхронмзации)

This commit is contained in:
RoyceDa
2026-02-08 18:40:03 +02:00
parent 7766afa984
commit c036275ed9
23 changed files with 1025 additions and 56 deletions

View File

@@ -0,0 +1,74 @@
package com.rosetta.im.database.entity;
import com.rosetta.im.database.CreateUpdateEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
/**
* Сущность для буфера сообщений, которые не были доставлены получателю, например,
* из-за того, что он был оффлайн, а так же для синхронизации сообщений
* между устройствами одного пользователя.
* Сообщения в буфере хранятся в виде сериализованных пакетов.
* Когда получатель становится онлайн, сервер пытается доставить ему все сообщения из буфера.
*/
@Entity
@Table(name = "packet_buffer")
public class Buffer extends CreateUpdateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "source")
private String from;
@Column(name = "destination")
private String to;
@Column(name = "packet", columnDefinition = "bytea")
private byte[] packet;
@Column(name = "timestamp")
private Long timestamp;
public Long getId() {
return id;
}
public String getFrom() {
return from;
}
public String getTo() {
return to;
}
public byte[] getPacket() {
return packet;
}
public Long getTimestamp() {
return timestamp;
}
public void setFrom(String from) {
this.from = from;
}
public void setTo(String to) {
this.to = to;
}
public void setPacket(byte[] packet) {
this.packet = packet;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
}

View File

@@ -0,0 +1,67 @@
package com.rosetta.im.database.entity;
import java.util.ArrayList;
import java.util.List;
import com.rosetta.im.database.CreateUpdateEntity;
import com.rosetta.im.database.converters.StringListConverter;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
/**
* Сущность для групповых чатов.
*/
@Entity
@Table(name = "groups")
public class Group extends CreateUpdateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "groupId")
private String groupId;
@Convert(converter = StringListConverter.class)
@Column(name = "membersPublicKeys", nullable = false)
private List<String> membersPublicKeys = new ArrayList<>();
@Convert(converter = StringListConverter.class)
@Column(name = "bannedPublicKeys", nullable = false)
private List<String> bannedPublicKeys = new ArrayList<>();
public Long getId() {
return id;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public List<String> getMembersPublicKeys() {
return membersPublicKeys;
}
public void setMembersPublicKeys(List<String> membersPublicKeys) {
this.membersPublicKeys = membersPublicKeys;
}
public List<String> getBannedPublicKeys() {
return bannedPublicKeys;
}
public void setBannedPublicKeys(List<String> bannedPublicKeys) {
this.bannedPublicKeys = bannedPublicKeys;
}
}

View File

@@ -0,0 +1,12 @@
package com.rosetta.im.database.repository;
import com.rosetta.im.database.Repository;
import com.rosetta.im.database.entity.Buffer;
public class BufferRepository extends Repository<Buffer> {
public BufferRepository() {
super(Buffer.class);
}
}

View File

@@ -21,5 +21,27 @@ public class DeviceRepository extends Repository<Device> {
return this.findAllByField("publicKey", user.getPublicKey());
}
/**
* Считает количество устройств пользователя
* @param user пользователь
* @return количество устройств
*/
public long countUserDevices(User user) {
return this.countByField("publicKey", user.getPublicKey());
}
/**
* Обновляет время последней активности устройства
* @param deviceId ID устройства
*/
public void updateDeviceLeaveTime(String deviceId) {
Device device = this.findByField("deviceId", deviceId);
if(device == null) {
return;
}
device.setLeaveTime(System.currentTimeMillis());
this.update(device);
}
}

View File

@@ -0,0 +1,28 @@
package com.rosetta.im.database.repository;
import java.util.ArrayList;
import java.util.List;
import com.rosetta.im.database.Repository;
import com.rosetta.im.database.entity.Group;
public class GroupRepository extends Repository<Group> {
public GroupRepository() {
super(Group.class);
}
/**
* Найти участников группы по groupId
* @param groupId ID группы
* @return список публичных ключей участников группы
*/
public List<String> findGroupMembers(String groupId) {
Group group = this.findByField("groupId", groupId);
if(group == null) {
return new ArrayList<>();
}
return group.getMembersPublicKeys();
}
}