From e73328461ef8a371a0adb0351d56387e87dd286b255fc76884cf89d23ac4eabe Mon Sep 17 00:00:00 2001 From: AidarKC Date: Fri, 1 May 2026 19:26:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B2=D0=BE=D0=BD=D0=BA=D0=B8:=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B1=D0=BE=D1=80=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B9=20cal?= =?UTF-8?q?lee-=D1=81=D0=B5=D1=81=D1=81=D0=B8=D0=B8=20=D0=B8=20=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE-=D0=B7=D0=B0=D0=BA=D1=80=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B2=D1=85=D0=BE=D0=B4=D1=8F=D1=89=D0=B5=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D0=B4=D1=80=D1=83=D0=B3=D0=B8=D1=85=20=D1=83?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION.properties | 4 +- shine-UI/js/services/call-service.js | 46 ++++++++++++++++++- .../Net_CallSignalToSession_Handler.java | 34 ++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) 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); + } + } }