我在循环中有一个MQTT调用,并且在每次迭代中,它应该返回订阅者的响应,以便我可以使用我发布后转发的值。但问题是我不知道我该怎么做。
我希望你有一个想法,或者如果我没有正确实施它,你可以引导我完成这个。感谢。
这是我的代码:
// MyClientMgr
class MyClientMgr{
public long CurrentOutput { get; set; }
public void GetCurrentOutput(MyObjectParameters parameters, MqttClient client)
{
MyMessageObject msg = new MyMessageObject
{
Action = MyEnum.GetOutput,
Data = JsonConvert.SerializeObject(parameters)
}
mq_GetCurrentOutput(msg, client);
}
private void mq_GetCurrentOutput(MyMessageObject msg, MqttClient client)
{
string msgStr = JsonConvert.SerializeObject(msg);
client.Publish("getOutput", Encoding.UTF8.GetBytes(msgStr),
MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
client.MqttMsgPublishReceived += (sender, e) =>{
MyObjectOutput output = JsonConvert.DeserializeObject<MyObjectOutput>(Encoding.UTF8.GetString(e.Message));
CurrentOutput = output;
};
}
}
// MyServerMgr
class MyServerMgr
{
public void InitSubscriptions()
{
mq_GetOutput();
}
private void mq_GetOutput()
{
MqttClient clientSubscribe = new MqttClient(host);
string clientId = Guid.NewGuid().ToString();
clientSubscribe.Connect(clientId);
clientSubscribe.Subscribe(new string[] { "getOutput" }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
MqttClient clientPublish = new MqttClient(host);
string clientIdPub = Guid.NewGuid().ToString();
clientPublish.Connect(clientIdPub);
clientSubscribe.MqttMsgPublishReceived += (sender, e) => {
MyMessageObj msg = JsonConvert.DeserializeObject<MyMessageObj>(Encoding.UTF8.GetString(e.Message));
var output = msg.Output;
clientPublish.Publish("getOutput", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(output)), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
}
}
}
// MyCallerClass
class MyCallerClass
{
var host = "test.mqtt.org";
var myServer = new MyServerMgr(host);
var myClient = new MyClientMgr();
myServer.InitSubscriptions();
MqttClient client = new MqttClient(host);
for(int i = 0; i < 10; i++)
{
long output = 0;
MyObjectParameters parameters = {};
myClient.GetCurrentOutput(parameters, client) // here I call the method from my client manager
// to publish the getting of the output and assigned
// below for use, but the problem is the value doesn't
// being passed to the output variable because it is not
// yet returned by the server.
// Is there a way I could wait the process to
// get the response before assigning the output?
output = myClient.CurrentOutput; // output here will always be null
// because the response is not yet forwarded by the server
}
}
我的调用者类中有一个循环来调用mqtt发布来获取输出,但是我不知道如何在分配之前获取输出,我想在转到下一个之前先等待响应。
我已经尝试过像这样做一个while循环:
while(output == 0)
{
output = myClient.CurrentOutput;
}
是的,我可以在这里获得输出,但它会减慢这个过程。有时它会失败。
请帮帮我。感谢。
答案 0 :(得分:0)
看起来您正在尝试通过异步协议(MQTT)进行同步通信。
我的意思是你要发送消息然后等待响应,这不是MQTT的工作原理,因为在协议级别没有回复消息的概念。
我对C#并不熟悉,所以我只是给出可能解决方案的抽象描述。
我的建议是使用发布线程,等待/脉冲(查看Monitor类)在每次发布后获得此块,并在收到响应时让消息处理程序调用脉冲。
如果响应没有等待识别原始请求,您还需要一个状态机变量来记录正在进行的请求。
你可能想看一下等待时间,以防另一方因某些原因没有回应。
答案 1 :(得分:0)
您可以使用具有WaitOne()和Set()方法的AutoResetEvent类。发布后使用WaitOne()将等待消息发布,并且在client_MqttMsgPublishReceived事件下使用Set()将在订阅者收到他订阅的消息时释放等待。