Files
rosetta-wss/src/main/java/im/rosetta/calls/CallSession.java

111 lines
4.6 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}