大華門禁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組發送消息。兩條消息是相對獨立的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM