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

120 lines
4.5 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.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import im.rosetta.client.ClientManager;
import im.rosetta.packet.Packet26SignalPeer;
import im.rosetta.packet.runtime.NetworkSignalType;
import io.g365sfu.Room;
import io.orprotocol.ProtocolException;
import io.orprotocol.client.Client;
import io.orprotocol.packet.Packet;
public class CallManager {
private List<CallSession> callSessions = new ArrayList<>();
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private static final long RINGING_TIMEOUT = 30 * 1000;
private ClientManager clientManager;
public CallManager(ClientManager clientManager) {
this.clientManager = clientManager;
scheduler.scheduleAtFixedRate(this::cleanupCallSessions, 0, 1, TimeUnit.SECONDS);
}
public void cleanupCallSessions() {
/**
* Такая конструкция нужна для избежания ConcurrentModificationException,
* так как мы не можем удалять элементы из списка, по которому проходим в цикле,
* поэтому мы сначала собираем сессии звонков, которые нужно удалить, а потом
* удаляем их из основного списка
*/
List<CallSession> sessionsToRemove = new ArrayList<>();
for (CallSession session : this.callSessions) {
if (session.shouldRemove()) {
/**
* Отправляем всем в сессии что звонок завершился, так как он устарел, и удаляем сессию из списка активных сессий
*/
Packet26SignalPeer rtout = new Packet26SignalPeer();
rtout.setSignalType(NetworkSignalType.RINGING_TIMEOUT);
Packet26SignalPeer endCallPacket = new Packet26SignalPeer();
endCallPacket.setSignalType(NetworkSignalType.END_CALL);
endCallPacket.setJoinToken(session.getJoinToken());
endCallPacket.setCallId(session.getCallId());
try {
session.sendPacket(rtout, null);
this.sendPacketToRinging(session, endCallPacket);
} catch (ProtocolException e) {
e.printStackTrace();
}
sessionsToRemove.add(session);
}
}
for (CallSession session : sessionsToRemove) {
this.callSessions.remove(session);
}
}
public CallSession createCall(String callId, String joinToken) {
CallSession session = new CallSession(callId, joinToken, RINGING_TIMEOUT);
this.callSessions.add(session);
return session;
}
public CallSession getCallSession(String callId, String joinToken) {
for (CallSession session : this.callSessions) {
if (session.getCallId().equals(callId) && session.getJoinToken().equals(joinToken)) {
return session;
}
}
return null;
}
public CallSession getCallSession(Room room) {
for (CallSession session : this.callSessions) {
if (session.getRoom() != null && session.getRoom().equals(room)) {
return session;
}
}
return null;
}
public boolean isBusy(String publicKey) {
for (CallSession session : this.callSessions) {
if (session.clients.containsKey(publicKey)) {
return true;
}
if(session.ringing.containsKey(publicKey)) {
return true;
}
}
return false;
}
public void sendPacketToRinging(CallSession session, Packet packet) throws ProtocolException {
for (String publicKey : session.ringing.keySet()) {
this.clientManager.sendPacketToAuthorizedPK(publicKey, packet);
}
}
public CallSession getCallSession(Client client) {
for (CallSession session : this.callSessions) {
if (session.clients.containsValue(client)) {
return session;
}
}
return null;
}
public void removeSession(CallSession session) {
this.callSessions.remove(session);
}
}