diff --git a/VERSION.properties b/VERSION.properties index a05e542..4ceba35 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.32 -server.version=1.2.26 +client.version=1.2.33 +server.version=1.2.27 diff --git a/shine-UI/js/services/call-service.js b/shine-UI/js/services/call-service.js index 821c213..55cb501 100644 --- a/shine-UI/js/services/call-service.js +++ b/shine-UI/js/services/call-service.js @@ -1366,7 +1366,51 @@ export async function handleIncomingCallSignal(evt) { const call = getCall(callId); if (!call) return; - if (!call.remoteSessionId) call.remoteSessionId = fromSessionId; + if (call.direction === 'out') { + if (type === TYPES.RINGING) { + if (!call.remoteSessionId && fromSessionId) { + call.remoteSessionId = fromSessionId; + } + if (call.remoteSessionId && fromSessionId && call.remoteSessionId !== fromSessionId) { + await emitDebug( + call, + 'info', + 'ringing_from_non_selected_session_ignored', + `selected=${call.remoteSessionId}; from=${fromSessionId}`, + ); + return; + } + } else if (type === TYPES.ACCEPT) { + if (fromSessionId) { + if (!call.remoteSessionId || !call.initialOfferSent) { + call.remoteSessionId = fromSessionId; + } else if (call.remoteSessionId !== fromSessionId) { + await emitDebug( + call, + 'warn', + 'accept_from_non_selected_session_ignored', + `selected=${call.remoteSessionId}; from=${fromSessionId}`, + ); + return; + } + } + } else { + if (call.remoteSessionId && fromSessionId && call.remoteSessionId !== fromSessionId) { + await emitDebug( + call, + 'info', + 'signal_from_non_selected_session_ignored', + `type=${type}; selected=${call.remoteSessionId}; from=${fromSessionId}`, + ); + return; + } + if (!call.remoteSessionId && fromSessionId) { + call.remoteSessionId = fromSessionId; + } + } + } else if (!call.remoteSessionId) { + call.remoteSessionId = fromSessionId; + } if (type === TYPES.RINGING) { if (call.direction === 'out' && call.phase === 'searching') { diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_CallSignalToSession_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_CallSignalToSession_Handler.java index d06b836..9db9a44 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_CallSignalToSession_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_CallSignalToSession_Handler.java @@ -20,6 +20,8 @@ import java.util.Set; public class Net_CallSignalToSession_Handler implements JsonMessageHandler { private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final int TYPE_ACCEPT = 120; + private static final int TYPE_HANGUP = 150; @Override public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) throws Exception { @@ -69,6 +71,10 @@ public class Net_CallSignalToSession_Handler implements JsonMessageHandler { boolean delivered = WsEventSender.sendEvent(targetCtx, "IncomingCallSignal", eventId, payload); + if (type == TYPE_ACCEPT) { + notifyAcceptedOnOtherSessions(ctx, callId); + } + Net_CallSignalToSession_Response resp = new Net_CallSignalToSession_Response(); resp.setOp(req.getOp()); resp.setRequestId(req.getRequestId()); @@ -76,4 +82,32 @@ public class Net_CallSignalToSession_Handler implements JsonMessageHandler { resp.setDelivered(delivered); return resp; } + + private void notifyAcceptedOnOtherSessions(ConnectionContext accepterCtx, String callId) { + if (accepterCtx == null) return; + String login = accepterCtx.getLogin(); + String acceptedSessionId = accepterCtx.getSessionId(); + if (login == null || login.isBlank() || acceptedSessionId == null || acceptedSessionId.isBlank() || callId == null || callId.isBlank()) { + return; + } + + Set sameUserSessions = ActiveConnectionsRegistry.getInstance().getByLogin(login); + for (ConnectionContext siblingCtx : sameUserSessions) { + if (siblingCtx == null || siblingCtx.getWsSession() == null || !siblingCtx.getWsSession().isOpen()) continue; + if (acceptedSessionId.equals(siblingCtx.getSessionId())) continue; + + String siblingEventId = NetIdGenerator.eventId("evt"); + ObjectNode siblingPayload = MAPPER.createObjectNode(); + siblingPayload.put("eventId", siblingEventId); + siblingPayload.put("fromLogin", login); + siblingPayload.put("fromSessionId", acceptedSessionId); + siblingPayload.put("toLogin", login); + siblingPayload.put("callId", callId); + siblingPayload.put("type", TYPE_HANGUP); + siblingPayload.put("data", "accepted_on_other_device"); + siblingPayload.put("timeMs", System.currentTimeMillis()); + + WsEventSender.sendEvent(siblingCtx, "IncomingCallSignal", siblingEventId, siblingPayload); + } + } }