package im.rosetta.executors; import im.rosetta.Failures; import im.rosetta.calls.CallManager; import im.rosetta.calls.CallSession; import im.rosetta.packet.Packet27WebRTC; import im.rosetta.packet.runtime.NetworkWebRTCType; import io.g365sfu.Room; import io.orprotocol.ProtocolException; import io.orprotocol.client.Client; import io.orprotocol.packet.PacketExecutor; public class Executor27WebRTC extends PacketExecutor { private CallManager callManager; public Executor27WebRTC(CallManager callManager) { this.callManager = callManager; } @Override public void onPacketReceived(Packet27WebRTC packet, Client client) throws Exception, ProtocolException { /** * Получаем, в какой сессии находится этот сокет */ CallSession session = this.callManager.getCallSession(client); if(session == null) { /** * Если сессия не найдена, то мы не будем обрабатывать сигналы для звонка */ return; } Room room = session.getRoom(); if(room == null) { /** * Звонок еще не активен, а значит комнаты еще нет. Нельзя обменяться WebRTC сигналами пока комнаты еще нет. */ return; } /** * Получаем публичный ключ, которым представился клиент, в рамках сессии звонка. * Мы не делаем это через ECIAuthentificate, так как в рамках звонка клиент может не быть авторизован, но при этом он уже находится в сессии звонка, и мы можем идентифицировать его по публичному ключу, * который он указал при присоединении к звонку используя joinToken. * Так что, несмотря на то, что клиент может быть не авторизован, мы все равно можем достоверно знать его публичный ключ */ String publicKey = session.getPublicKey(client); if(publicKey == null) { /** * Избыточная проверка, так как если клиент находится в сессии, то он должен быть в списке клиентов сессии, * но на всякий случай проверим это, чтобы избежать возможных ошибок */ client.disconnect(Failures.DATA_MISSMATCH); return; } NetworkWebRTCType type = packet.getType(); if(type == NetworkWebRTCType.OFFER) { /** * Если это OFFER, то отправляем OFFER на сервер SFU, * который отвечает за эту комнату, чтобы он транслировал его всем участникам комнаты, кроме отправителя */ room.sdpOffer(publicKey, packet.getSdpOrCandidate()); } if(type == NetworkWebRTCType.ICE_CANDIDATE) { /** * Если это ICE кандидат, то отправляем его на сервер SFU, * который отвечает за эту комнату, чтобы он транслировал его всем участникам комнаты, кроме отправителя */ room.iceCandidate(publicKey, packet.getSdpOrCandidate()); } if(type == NetworkWebRTCType.ANSWER) { /** * Если это ANSWER, то отправляем его на сервер SFU, * который отвечает за эту комнату, чтобы он транслировал его всем участникам комнаты, кроме отправителя */ room.sdpAnswer(publicKey, packet.getSdpOrCandidate()); } } }