大華門禁SDK二次開發(二)
阿新 • • 發佈:2018-11-22
經過與大華技術支援的溝通,門禁服務程式已經開發好了,可以正常接收門禁開關事件,可以傳送開門命令。基於專案實時性要求,這裡使用SignalR實現門禁狀態、控制命令的實時傳送。
幾種場景需求
根據SignalR的設計規則,Client端可以主動呼叫服務端Hub的多個方法,但是客戶端被動接收訊息的方法只能有一個。
根據門禁功能需求,我們將Client分為兩組:
- doorclient:指Web客戶端
- doorserver:指門禁服務端
這樣便於服務端區分Web客戶端和門禁服務端這兩類client。
專案中主要實現以下幾個場景:
Web客戶端初始載入,重新整理全部門禁狀態
- 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端請求開啟某個門
- 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); }
門禁服務傳送門禁狀態變化
- A.這種情況主要發生在門禁刷卡等開門操作,引起的門禁狀態變化,門禁服務接收到訊息後,主動傳送門禁狀態變化資訊;
- B.web服務端接收資訊,並轉發到doorclient組。
幾個問題說明
AddMessage方法
客戶端使用AddMessage
接收server轉發來的訊息,由於client監聽接收訊息只能有一個方法,但是存在單個門禁狀態變化訊息和多個兩種情況。因此AddMessage
的訊息引數統一使用List<Message>
,然後在server端轉發時相應加入業務標記,便於client端處理。
門禁服務程式的事件機制
門禁服務程式採用事件機制
- 刷卡等開發事件接收到後,門禁服務會主動進行訊息傳送,通知所有瀏覽器更新相應門禁狀態;
- 瀏覽器初始化請求所有門禁狀態時,由於訊息通訊是不能直接返回的,因此資訊傳遞時攜帶connectId,用於下一條訊息確認傳送物件;
- 與初始化請求一樣,瀏覽器傳送開門命令後,門禁服務接收到開門命令傳送給大華門禁伺服器後,會在收到門禁狀態變化事件時,向doorclient組傳送訊息。兩條訊息是相對獨立的。