zoukankan      html  css  js  c++  java
  • 大华门禁SDK二次开发(二)-SignalR应用

    经过与大华技术支持的沟通,门禁服务程序已经开发好了,可以正常接收门禁开关事件,可以发送开门命令。基于项目实时性要求,这里使用SignalR实现门禁状态、控制命令的实时传送。

    几种场景需求

    根据SignalR的设计规则,Client端可以主动调用服务端Hub的多个方法,但是客户端被动接收消息的方法只能有一个
    根据门禁功能需求,我们将Client分为两组:

    • doorclient:指Web客户端
    • doorserver:指门禁服务端

    这样便于服务端区分Web客户端和门禁服务端这两类client。

    总结构.png

    项目中主要实现以下几个场景:

    Web客户端初始加载,刷新全部门禁状态

    初始化门禁.png

    • A. 浏览器主动请求初始化门禁状态;
    • B. web服务端接收信息,并转发到doorserver组;
    • C. 门禁服务查询门禁状态,主动发送门禁状态列表;
    • D. web服务端接收消息,并根据connectId转发给指定浏览器。
    //web客户端
    chat.server.sendMessageByBrowser();
    
    // 定义AddMessage供服务器调用
    chat.client.AddMessage = function (result) {
        for (var i = 0; i < result.length; i++) {
            try {
                //前端响应门禁状态变化
            } catch (error) {
            }
        }
    };
    
    //web服务端
    /// <summary>
    /// 浏览器发送消息,向doorServer请求所有门禁状态,用于初始化门禁状态
    /// </summary>
    /// <param name="name"></param>
    public void SendMessageByBrowser()
    {
        var messageList = new List<DoorStateInfo>();
        var dc = new DoorStateInfo {ConnectId = Context.ConnectionId};
        messageList.Add(dc);
        Clients.Group("doorserver").AddMessage(messageList);
    }
    
    
    /// <summary>
    /// 门禁服务发送多条开关门消息给某个浏览器,hubserver转发给浏览器
    /// 浏览器id放在messagelist[0].ConnectId
    /// </summary>
    /// <param name="name"></param>
    /// <param name="messageList"></param>
    public void SendManyMessageByDoorServer(string name, List<DoorStateInfo> messageList)
    {
        Clients.Client(messageList[0].ConnectId).AddMessage(messageList);
    }
    
    //门禁服务端
    // 创建一个集线器代理对象
    HubProxy = Connection.CreateHubProxy("DoorAlarmHub");
    
    // 供服务端调用,将消息输出到消息列表框中
    HubProxy.On<string, List<DoorStateInfo>>("AddMessage", (message) =>
    {
        var alarmMsg = new AlarmMsg
        {
            Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
            AlarmInfo = message,
            AlarmType = EM_ALARM_TYPE.ALARM_SIGNALR_QUERY
        };
        if (message != null && message.Count > 0) 
        {
            //无门禁状态,为门禁查询命令
            if (message[0].DoorState == EM_NET_DOOR_STATUS_TYPE.EM_NET_DOOR_STATUS_UNKNOWN)
            {
                alarmMsg.AlarmType = EM_ALARM_TYPE.ALARM_SIGNALR_QUERY;
            }
            //有门禁状态,为门禁控制命令
            else 
            {
                alarmMsg.AlarmType = EM_ALARM_TYPE.ALARM_SIGNALR_CONTROL;
            }
            m_AlarmMsgQueue.Enqueue(alarmMsg);                    
        }
    });
    

    Web端请求打开某个门

    打开某个门.png

    • A. 浏览器主动请求开门;
    • B. web服务端接收信息,并转发到doorserver组;
    • C. 门禁服务发送开门命令,接收到门禁状态变化消息后,主动发送门禁状态变化信息;
    • D. web服务端接收信息,并转发到doorclient组。
    //web服务端
    /// <summary>
    /// 浏览器端调用,请求开门
    /// </summary>
    public void SendOpenDoorByBrowser(/*业务参数用于标识门禁*/)
    {
        
        var messageList = new List<DoorStateInfo>();
        
        //业务处理
        ...
        
        Clients.Group("doorserver").AddMessage("doorserver", messageList);
    }
    
    
    /// <summary>
    /// 门禁服务发送开关门消息,hubserver转发给浏览器
    /// </summary>
    /// <param name="name"></param>
    /// <param name="message"></param>
    public void SendOneMessageByDoorServer(string name, DoorStateInfo message)
    {
        
        //业务处理
        Clients.Group("doorclient").AddMessage(message);            
    }
    

    门禁服务发送门禁状态变化

    发送状态变化.png

    • A.这种情况主要发生在门禁刷卡等开门操作,引起的门禁状态变化,门禁服务接收到消息后,主动发送门禁状态变化信息;
    • B.web服务端接收信息,并转发到doorclient组。

    几个问题说明

    AddMessage方法

    客户端使用AddMessage接收server转发来的消息,由于client监听接收消息只能有一个方法,但是存在单个门禁状态变化消息和多个两种情况。因此AddMessage的消息参数统一使用List<Message>,然后在server端转发时相应加入业务标记,便于client端处理。

    门禁服务程序的事件机制

    门禁服务程序采用事件机制

    • 刷卡等开发事件接收到后,门禁服务会主动进行消息发送,通知所有浏览器更新相应门禁状态;
    • 浏览器初始化请求所有门禁状态时,由于消息通信是不能直接返回的,因此信息传递时携带connectId,用于下一条消息确认发送对象;
    • 与初始化请求一样,浏览器发送开门命令后,门禁服务接收到开门命令发送给大华门禁服务器后,会在收到门禁状态变化事件时,向doorclient组发送消息。两条消息是相对独立的。
  • 相关阅读:
    linux分析、诊断及调优必备的“杀器”之二
    浏览器被“hao123.3377.com”主页劫持的解决办法
    Nginx一个实现负载均衡的强大web server
    【百度之星
    c/c++ 参数传递
    【百度之星】-IP聚合
    百度之星-大搬家-递推
    IOS开发之Swift学习笔记
    【Leetcode】84. Largest Rectangle in Histogram 85. Maximal Rectangle
    【Leetcode】82. Remove Duplicates from Sorted List II
  • 原文地址:https://www.cnblogs.com/zhangdk/p/SignalR.html
Copyright © 2011-2022 走看看