public void Close() { lastException = null; if (mqttClient != null && mqttClient.IsConnected) { GXMessage msg = new GXMessage() { id = MessageId, type = (int)MesssageType.Close, sender = clientId }; try { PublishMessage(msg); } catch (Exception) { replyReceivedEvent.Set(); } if (AsyncWaitTime == 0) { replyReceivedEvent.WaitOne(); } else { replyReceivedEvent.WaitOne((int)AsyncWaitTime * 1000); } mqttClient.DisconnectAsync().Wait(); mqttClient = null; if (lastException != null) { throw new Exception(lastException); } } }
/// <summary> /// Publish message. /// </summary> /// <param name="msg"></param> private void PublishMessage(GXMessage msg) { GXJsonParser parser = new GXJsonParser(); string str = parser.Serialize(msg); MqttApplicationMessage message = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message).Wait(); }
void IGXMedia.Send(object data, string receiver) { byte[] tmp = (byte[])data; if (tmp != null) { BytesSent += (ulong)tmp.Length; GXMessage msg = new GXMessage() { id = MessageId, type = (int)MesssageType.Send, sender = clientId, frame = Common.GXCommon.ToHex(tmp) }; PublishMessage(msg); } }
public void Open() { Close(); mqttClient = factory.CreateMqttClient(); if (string.IsNullOrEmpty(userClientId)) { clientId = Guid.NewGuid().ToString(); } else { clientId = userClientId; } var options = new MqttClientOptionsBuilder() .WithTcpServer(serverAddress, port).WithClientId(clientId) .Build(); mqttClient.UseApplicationMessageReceivedHandler(t => { string str = ASCIIEncoding.ASCII.GetString(t.ApplicationMessage.Payload); GXJsonParser parser = new GXJsonParser(); GXMessage msg = parser.Deserialize <GXMessage>(str); if (msg.id == messageId || (MesssageType)msg.type == MesssageType.Close || (MesssageType)msg.type == MesssageType.Exception) { switch ((MesssageType)msg.type) { case MesssageType.Open: m_OnMediaStateChange?.Invoke(this, new MediaStateEventArgs(MediaState.Open)); replyReceivedEvent.Set(); break; case MesssageType.Send: break; case MesssageType.Receive: byte[] bytes = Gurux.Common.GXCommon.HexToBytes(msg.frame); replyReceivedEvent.Set(); if (bytes.Length != 0) { HandleReceivedData(bytes.Length, bytes, t.ClientId); } break; case MesssageType.Close: m_OnMediaStateChange?.Invoke(this, new MediaStateEventArgs(MediaState.Closed)); replyReceivedEvent.Set(); break; case MesssageType.Exception: lastException = msg.exception; replyReceivedEvent.Set(); break; } } else { m_OnTrace?.Invoke(this, new TraceEventArgs(TraceTypes.Info, "Unknown reply. " + msg, msg.sender)); } }); mqttClient.UseConnectedHandler(t => { // Subscribe to a topic mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(clientId).WithExactlyOnceQoS().Build()).Wait(); m_OnMediaStateChange?.Invoke(this, new MediaStateEventArgs(MediaState.Opening)); GXMessage msg = new GXMessage() { id = MessageId, type = (int)MesssageType.Open, sender = clientId }; PublishMessage(msg); }); mqttClient.UseDisconnectedHandler(t => { m_OnMediaStateChange?.Invoke(this, new MediaStateEventArgs(MediaState.Closed)); replyReceivedEvent.Set(); }); try { replyReceivedEvent.Reset(); if (AsyncWaitTime == 0) { mqttClient.ConnectAsync(options).Wait(); } else { mqttClient.ConnectAsync(options).Wait((int)AsyncWaitTime * 1000); } } catch (AggregateException ex) { if (mqttClient != null) { mqttClient.DisconnectAsync().Wait(10000); } mqttClient = null; throw ex.InnerException; } if (AsyncWaitTime == 0) { replyReceivedEvent.WaitOne(); } else { if (!replyReceivedEvent.WaitOne((int)AsyncWaitTime * 1000)) { throw new TimeoutException("Invalid topic '" + topic + "'."); } } if (lastException != null) { throw new Exception(lastException); } }
public static void Start(TraceLevel trace, string server, int port, Connection connection) { // Create a new MQTT client. var mqttClient = factory.CreateMqttClient(); int pos = 1; foreach (var it in connection.Connections) { if (it.Type == "Net") { it.Target = new GXNet() { Settings = it.Settings }; } else if (it.Type == "Serial") { it.Target = new GXSerial() { Settings = it.Settings }; } else { throw new Exception("Unknown media type." + it.Type); } if (string.IsNullOrEmpty(it.Name)) { it.Name = connection.Name + "/" + pos.ToString(); ++pos; } else { it.Name = connection.Name + "/" + it.Name; } it.Target.OnReceived += (s, e) => { string tmp = GXCommon.ToHex((byte[])e.Data, true); if (trace == TraceLevel.Verbose) { Console.WriteLine("Received: " + tmp); } foreach (var it2 in connection.Connections) { if (it2.Target == s) { GXMessage msg = new GXMessage() { id = it2.Message.id, type = (int)MesssageType.Receive, sender = it2.Name, frame = tmp }; GXJsonParser parser = new GXJsonParser(); string str = parser.Serialize(msg); var message = new MqttApplicationMessageBuilder() .WithTopic(it2.Message.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); break; } } }; } ShowInformation(connection); var options = new MqttClientOptionsBuilder() .WithTcpServer(server, port) .WithClientId(connection.Name) .Build(); mqttClient.UseApplicationMessageReceivedHandler(t => { string str = ASCIIEncoding.ASCII.GetString(t.ApplicationMessage.Payload); GXJsonParser parser = new GXJsonParser(); GXMessage msg = parser.Deserialize <GXMessage>(str); if (trace == TraceLevel.Verbose) { Console.WriteLine("---Received message"); Console.WriteLine($"+ Topic = {t.ApplicationMessage.Topic}"); Console.WriteLine($"+ Payload = {msg.frame}"); Console.WriteLine($"+ QoS = {t.ApplicationMessage.QualityOfServiceLevel}"); Console.WriteLine($"+ Retain = {t.ApplicationMessage.Retain}"); } GXMessage msg2; MqttApplicationMessage message; foreach (var it in connection.Connections) { if (it.Name == t.ApplicationMessage.Topic) { it.Message = msg; try { switch ((MesssageType)msg.type) { case MesssageType.Open: it.Target.Open(); try { //Move to mode E if optical head is used. if (it.Target is GXSerial && it.UseOpticalHead) { InitializeIEC(trace, it); } if (it.Target is IGXMedia2) { ((IGXMedia2)it.Target).ReceiveDelay = 500; } //Mark EOP so reading is faster. // it.Target.Eop = (byte)0x7e; } catch (Exception ex) { it.Target.Close(); throw ex; } msg2 = new GXMessage() { id = msg.id, type = (int)MesssageType.Open, sender = it.Name }; str = parser.Serialize(msg2); message = new MqttApplicationMessageBuilder() .WithTopic(msg.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); break; case MesssageType.Send: it.Target.Send(GXCommon.HexToBytes(msg.frame), null); break; case MesssageType.Close: it.Target.Close(); msg2 = new GXMessage() { id = msg.id, type = (int)MesssageType.Close, sender = it.Name }; str = parser.Serialize(msg2); message = new MqttApplicationMessageBuilder() .WithTopic(msg.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); break; } } catch (Exception ex) { msg2 = new GXMessage() { id = msg.id, type = (int)MesssageType.Exception, sender = it.Name, exception = ex.Message }; str = parser.Serialize(msg2); message = new MqttApplicationMessageBuilder() .WithTopic(msg.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); } break; } } }); mqttClient.UseConnectedHandler(t => { if (trace > TraceLevel.Warning) { Console.WriteLine("--- Connected with the server. " + t.AuthenticateResult.IsSessionPresent); } // Subscribe to a topic List <TopicFilter> topics = new List <TopicFilter>(); foreach (Media it in connection.Connections) { topics.Add(new TopicFilterBuilder().WithTopic(it.Name).Build()); } mqttClient.SubscribeAsync(topics.ToArray()); if (trace > TraceLevel.Warning) { Console.WriteLine("--- Subscribed. "); } }); mqttClient.UseDisconnectedHandler(t => { Console.WriteLine("--- Disconnected from the server. " + t.Exception); //Try to re-connect. while (true) { try { foreach (var it in connection.Connections) { it.Target.Close(); } Console.WriteLine("--- Try to reconnect to the server."); mqttClient.ConnectAsync(options).Wait(10000); Console.WriteLine("--- Connected with the server. "); break; } catch (Exception ex) { Console.WriteLine("--- Failed to reconnect to the server. " + ex.Message); } } }); mqttClient.ConnectAsync(options).Wait(); }