111 lines
4.6 KiB
Java
111 lines
4.6 KiB
Java
package im.rosetta.calls;
|
||
|
||
import java.util.HashMap;
|
||
|
||
import io.g365sfu.Room;
|
||
import io.orprotocol.ProtocolException;
|
||
import io.orprotocol.client.Client;
|
||
import io.orprotocol.packet.Packet;
|
||
|
||
public class CallSession {
|
||
|
||
public String callId;
|
||
public String joinToken;
|
||
public Long createdAt;
|
||
public Long ringingTimeout;
|
||
/**
|
||
* Клиенты которым сейчас идет дозвон (публичные ключи)
|
||
* Клиенты в этом списке не могут принимать другие звонки, так как они уже заняты дозвоном,
|
||
* но они еще не в звонке, так как не приняли звонок
|
||
*
|
||
* Клиенты удаляются из этого списка, когда они принимают звонок или отклоняют его, тогда они либо переходят в звонок, либо становятся свободными для других звонков
|
||
*/
|
||
public HashMap<String, Long> ringing;
|
||
/**
|
||
* Клиенты, которые уже приняли звонок и находятся в звонке (публичные ключи) и их сокеты
|
||
* pk -> client
|
||
*/
|
||
public HashMap<String, Client> clients;
|
||
/**
|
||
* Если звонок активен у него появляется комната, иначе комната null
|
||
*/
|
||
public Room room;
|
||
|
||
|
||
public CallSession(String callId, String joinToken, Long ringingTimeout) {
|
||
this.callId = callId;
|
||
this.joinToken = joinToken;
|
||
this.clients = new HashMap<>();
|
||
this.ringing = new HashMap<>();
|
||
this.createdAt = System.currentTimeMillis();
|
||
this.ringingTimeout = ringingTimeout;
|
||
}
|
||
|
||
public void joinCall(String publicKey, Client client) {
|
||
if(this.ringing.containsKey(publicKey)) {
|
||
this.ringing.remove(publicKey);
|
||
}
|
||
this.clients.put(publicKey, client);
|
||
}
|
||
|
||
/**
|
||
* Получаем публичный ключ клиента по его сокету, чтобы понимать, кто отправляет сигналы в рамках звонка
|
||
* @param client Сокет клиента, для которого нужно получить публичный ключ
|
||
* @return Публичный ключ клиента, или null если клиент не найден в сессии звонка
|
||
*/
|
||
public String getPublicKey(Client client) {
|
||
for (String publicKey : this.clients.keySet()) {
|
||
if (this.clients.get(publicKey).equals(client)) {
|
||
return publicKey;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public String getCallId() {
|
||
return this.callId;
|
||
}
|
||
|
||
public String getJoinToken() {
|
||
return this.joinToken;
|
||
}
|
||
|
||
public void addRinging(String publicKey) {
|
||
this.ringing.put(publicKey, System.currentTimeMillis());
|
||
}
|
||
|
||
public void setRoom(Room room) {
|
||
this.room = room;
|
||
}
|
||
|
||
public Room getRoom() {
|
||
return this.room;
|
||
}
|
||
|
||
/**
|
||
* Отправляем пакет всем участникам звонка, кроме исключенного клиента (обычно отправителя)
|
||
* @param packet Пакет для отправки
|
||
* @param excludeClient Клиент, которому не нужно отправлять пакет (обычно отправитель)
|
||
* @throws ProtocolException Если произошла ошибка при отправке пакета клиенту
|
||
*/
|
||
public void sendPacket(Packet packet, Client excludeClient) throws ProtocolException {
|
||
for (Client client : this.clients.values()) {
|
||
if (!client.equals(excludeClient)) {
|
||
client.send(packet);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Проверяем, нужно ли удалять сессию звонка.
|
||
* Сессию звонка нужно удалять, если в ней меньше 2 клиентов и при этом нет клиентов в состоянии дозвона,
|
||
* или если сессия была создана более 1 минуты назад, так как это значит, что клиенты не ответили на звонок и он устарел
|
||
* @return true, если сессию звонка нужно удалять, false иначе
|
||
*/
|
||
public boolean shouldRemove() {
|
||
return this.clients.size() <= 1 && (this.ringing.size() == 0 || System.currentTimeMillis() - this.createdAt > this.ringingTimeout);
|
||
}
|
||
|
||
|
||
}
|