SessionManager.java 2.5 KB
package com.genersoft.iot.vmp.jtt1078.server;

import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 会话管理器
 * 负责维护 Netty Channel 与 设备标识 的映射关系
 */
public class SessionManager {

    private static final Logger logger = LoggerFactory.getLogger(SessionManager.class);

    // 维护 Tag 到 Netty Channel 的映射
    private static final Map<String, Channel> tagToChannelMap = new ConcurrentHashMap<>();

    public static void init() {
        tagToChannelMap.clear();
        logger.info("SessionManager initialized.");
    }

    /**
     * 绑定属性到 Channel,并建立反向索引
     */
    public static void set(Channel channel, String key, Object value) {
        if (channel == null || key == null) return;

        // 1. 设置 Channel 内部属性
        channel.attr(AttributeKey.valueOf(key)).set(value);

        // 2. 【核心修复】建立反向索引
        // 同时支持 "tag" (视频流专用,可能带后缀) 和 "intercom_tag" (对讲专用,纯净SIM-通道)
        // 这样 WebSocket 使用 "sim-channel" 也能查找到连接,互不影响
        if (("tag".equals(key) || "intercom_tag".equals(key)) && value instanceof String) {
            String tagValue = (String) value;
            tagToChannelMap.put(tagValue, channel);
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T get(Channel channel, String key) {
        if (channel == null) return null;
        return (T) channel.attr(AttributeKey.valueOf(key)).get();
    }

    public static boolean contains(Channel channel, String key) {
        if (channel == null) return false;
        return channel.attr(AttributeKey.valueOf(key)).get() != null;
    }

    /**
     * WebSocket 调用此方法查找设备连接
     */
    public static Channel getChannelByTag(String tag) {
        if (tag == null) return null;
        return tagToChannelMap.get(tag);
    }

    public static void remove(Channel channel) {
        if (channel == null) return;

        // 清理关联的 tag
        String tag = get(channel, "tag");
        if (tag != null) tagToChannelMap.remove(tag);

        // 清理关联的 intercom_tag
        String intercomTag = get(channel, "intercom_tag");
        if (intercomTag != null) tagToChannelMap.remove(intercomTag);
    }

    public static int getSessionCount() {
        return tagToChannelMap.size();
    }
}