//------------------------------------------------------------------------------------------------------------------------ public void OnRxRsp(MqttMsg wrapper_msg, object api_msg) { //sanity check DebugEx.Assert(wrapper_msg.SyncId != 0, "Responses must have syncId set to a non-zero number"); if (wrapper_msg.SyncId == 0) { return; } //get id int syncId = wrapper_msg.SyncId; //find blocked transaction, if any RpcBlocker w = null; lock (RpcPending) if (RpcPending.TryGetValue(syncId, out w)) { RpcPending.Remove(syncId); } //remove if found //set result and wake if (w != null) { lock (w) { w.Response = api_msg; Monitor.Pulse(w); } } else { DebugEx.TraceError("Could not find mqtt waiter from response message with ResponseToSeqNo=" + syncId); } }
//------------------------------------------------------------------------------------------------------------------------ public Trsp SendRequest <Trsp>(API.ApiMsg request, TimeSpan?timeout = null) { //check if (request == null) { DebugEx.Assert("Request msg cannot be null"); return(default(Trsp)); } //set default timeout if (timeout == null) { timeout = TimeSpan.FromSeconds(15); } //generate ID int syncId = GetNewSyncId(); //create msg MqttMsg msg; try { msg = new MqttMsg() { IsRequest = true, SyncId = syncId, Payload = request.ToJSON(HtmlEncode: false) }; } catch (Exception ex) { DebugEx.Assert(ex, "Could not create request msg"); return(default(Trsp)); } //create waiter var w = new RpcBlocker(); lock (RpcPending) RpcPending.Add(syncId, w); //wait for response lock (w) { //publish msg if (request is Yodiwo.API.Warlock.WarlockApiMsg) { this.MqttClient.PublishMqttMsg(msg, this.mqttCloudBrokerPubTopicPrefix + Yodiwo.API.Warlock.WarlockAPI.ApiMsgNames[request.GetType()]); } else if (request is Yodiwo.API.Plegma.PlegmaApiMsg) { this.MqttClient.PublishMqttMsg(msg, this.mqttCloudBrokerPubTopicPrefix + PlegmaAPI.ApiMsgNames[request.GetType()]); } if (timeout == null) { Monitor.Wait(w); } else { Monitor.Wait(w, timeout.Value); } } //remove if found lock (RpcPending) RpcPending.Remove(syncId); //give response back if (w.Response == null) { return(default(Trsp)); } else { return((Trsp)w.Response); } }