feat: 增加请求弹窗和拒绝说明

This commit is contained in:
2026-07-15 21:40:00 +08:00
parent 839a980b45
commit f1457e68eb
13 changed files with 645 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
package com.ttstd.signaling.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ttstd.signaling.manager.ConnectionRequestManager;
import com.ttstd.signaling.manager.SessionManager;
import com.ttstd.signaling.model.DeviceType;
import com.ttstd.signaling.model.SignalMessage;
@@ -24,9 +25,24 @@ public class SignalWebSocketHandler extends TextWebSocketHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
private final SessionManager sessionManager;
private final ConnectionRequestManager connectionRequestManager;
public SignalWebSocketHandler(SessionManager sessionManager) {
public SignalWebSocketHandler(SessionManager sessionManager, ConnectionRequestManager connectionRequestManager) {
this.sessionManager = sessionManager;
this.connectionRequestManager = connectionRequestManager;
this.connectionRequestManager.setSender(this::sendToDevice);
}
/**
* 向指定设备回送服务端事件(错误/超时通知等)。
*/
private void sendToDevice(String deviceId, Object message) {
WebSocketSession session = sessionManager.getSession(deviceId);
if (session == null || !session.isOpen()) {
logger.warn("Cannot send event to {}: device offline", deviceId);
return;
}
sendToSession(session, message);
}
@Override
@@ -56,10 +72,21 @@ public class SignalWebSocketHandler extends TextWebSocketHandler {
handleDeviceList(session, signalMessage);
break;
case "OFFER":
// 连接请求:统一经 ConnectionRequestManager 做校验/去重/待确认跟踪后再转发
handleConnectionRequest(signalMessage);
break;
case "ANSWER":
// 关键信令:目标不在线时回送 TARGET_OFFLINE 提醒发送方
// 被控端已接受:清理待确认状态并转发 Answer 给主控端
connectionRequestManager.completePendingRequest(
signalMessage.getToDeviceId(), signalMessage.getFromDeviceId());
forwardMessage(signalMessage, true);
break;
case "CONNECTION_REJECTED":
// 被控端已拒绝:清理待确认状态并转发拒绝通知给主控端
connectionRequestManager.completePendingRequest(
signalMessage.getToDeviceId(), signalMessage.getFromDeviceId());
forwardMessage(signalMessage, false);
break;
case "ICE_CANDIDATE":
case "CONTROL_COMMAND":
// 普通信令:目标不在线时静默丢弃,不返回提示
@@ -126,6 +153,44 @@ public class SignalWebSocketHandler extends TextWebSocketHandler {
sendToSession(session, response);
}
/**
* 处理主控端发来的连接请求OFFER先做设备类型校验与去重
* 再登记“待被控端确认”状态,最后转发给被控端。
*/
private void handleConnectionRequest(SignalMessage message) {
String fromDeviceId = message.getFromDeviceId();
String toDeviceId = message.getToDeviceId();
// 1. 校验:仅允许 CONTROLLER -> CONTROLLED
String error = connectionRequestManager.validateOffer(fromDeviceId, toDeviceId);
if (error != null) {
logger.warn("Invalid connection request {} -> {}: {}", fromDeviceId, toDeviceId, error);
Map<String, Object> response = new HashMap<>();
response.put("type", "REQUEST_ERROR");
response.put("toDeviceId", toDeviceId);
response.put("payload", error);
sendToDevice(fromDeviceId, response);
return;
}
// 2. 去重:短时间内重复 OFFER 直接忽略,避免被控端反复弹窗
if (connectionRequestManager.isDuplicateOffer(fromDeviceId, toDeviceId)) {
logger.info("Duplicate connection request {} -> {} ignored", fromDeviceId, toDeviceId);
return;
}
// 3. 目标不在线:立即回送 TARGET_OFFLINE且不登记待确认避免等待超时
if (!sessionManager.isDeviceOnline(toDeviceId)) {
logger.warn("Target device {} is offline, cannot deliver connection request", toDeviceId);
notifySenderTargetOffline(message, toDeviceId);
return;
}
// 4. 登记待确认并转发 OFFER 给被控端
connectionRequestManager.registerPendingRequest(fromDeviceId, toDeviceId);
forwardMessage(message, false);
}
private void forwardMessage(SignalMessage message, boolean notifyOffline) {
String toDeviceId = message.getToDeviceId();
if (toDeviceId == null) {