public void Send(MqMessage msg) { _stream.Send(msg); if (_pl.verbose) { Log.Debug("S {0} < {1}", this.Signature, msg); } }
public static MqMessage Parse(byte header, uint len, MemoryStream stream) { MqMessage msg = null; switch ((MessageType)((header & 0xf0) >> 4)) { case MessageType.CONNECT: msg = new MqConnect(header, len, stream); break; case MessageType.CONNACK: msg = new MqConnack(header, len, stream); break; case MessageType.DISCONNECT: msg = new MqDisconnect(header, len, stream); break; case MessageType.PINGREQ: msg = new MqPingReq(header, len, stream); break; case MessageType.PINGRESP: msg = new MqPingResp(header, len, stream); break; case MessageType.PUBLISH: msg = new MqPublish(header, len, stream); break; case MessageType.SUBSCRIBE: msg = new MqSubscribe(header, len, stream); break; case MessageType.SUBACK: msg = new MqSuback(header, len, stream); break; case MessageType.UNSUBSCRIBE: msg = new MqUnsubscribe(header, len, stream); break; case MessageType.UNSUBACK: msg = new MqUnsuback(header, len, stream); break; case MessageType.PUBACK: case MessageType.PUBCOMP: case MessageType.PUBREC: case MessageType.PUBREL: msg = new MqMsgAck(header, len, stream); break; } return(msg); }
private void SendIntern(MqMessage msg) { if (msg == null || _waitAck == null) { return; } MemoryStream ms = new MemoryStream(); msg.Serialise(ms); try { _stream.BeginWrite(ms.GetBuffer(), 0, (int)ms.Length, _sendCB, null); } catch (IOException) { if (this._connected) { this.Close(); } return; } catch (ObjectDisposedException) { return; } catch (Exception ex) { string re; try{ re = Socket.Client.RemoteEndPoint.ToString(); } catch (Exception) { re = "UNK"; } Log.Warning("MqStreamer.SendIntern({0}, {1}) - {2}", msg.ToString(), re, ex.ToString()); } if (msg.QualityOfService != QoS.AtMostOnce && !msg.Duplicate) { _waitAck.Add(new wMessage(msg)); } msg.Duplicate = true; if (msg.MsgType == MessageType.DISCONNECT) { Thread.Sleep(30); // hack, wait fo buffers flush Close(true); } }
/// <summary> Send Message to broker</summary> /// <param name="msg">MQTT message</param> /// <remarks>Upon receipt of subscription switches to pause. /// Resumes at a pause in the receive of data over 300 ms. /// When paused publish are not sent</remarks> public void Send(MqMessage msg) { if(msg.QualityOfService!=QoS.AtMostOnce && msg.MessageID==0) { int tmp=Interlocked.Increment(ref _messageIdGen); if((tmp & 0x7FFF)==0) { tmp=Interlocked.Increment(ref _messageIdGen); _messageIdGen=(ushort)tmp; } if(Topic.brokerMode) { tmp^=0x8000; } msg.MessageID=(ushort)tmp; } if((!_sndPaused || msg.MsgType!=MessageType.PUBLISH) && Interlocked.Exchange(ref _sendProcessed, 1)==0) { SendIntern(msg); } else { lock(_sendQ) { _sendQ.Enqueue(msg); } } }
/// <summary> Send Message to broker</summary> /// <param name="msg">MQTT message</param> /// <remarks>Upon receipt of subscription switches to pause. /// Resumes at a pause in the receive of data over 300 ms. /// When paused publish are not sent</remarks> public void Send(MqMessage msg) { if (msg.QualityOfService != QoS.AtMostOnce && msg.MessageID == 0) { int tmp = Interlocked.Increment(ref _messageIdGen); if ((tmp & 0x7FFF) == 0) { tmp = Interlocked.Increment(ref _messageIdGen); _messageIdGen = (ushort)tmp; } tmp ^= 0x8000; msg.MessageID = (ushort)tmp; } if (Interlocked.Exchange(ref _sendProcessed, 1) == 0) { SendIntern(msg); } else { lock (_sendQ) { _sendQ.Enqueue(msg); } } }
private void Send(MqMessage msg) { _stream.Send(msg); if(_verbose.value) { Log.Debug("S {0}", msg); } }
private void Received(MqMessage msg) { if(_verbose.value) { Log.Debug("R {0}", msg); } switch(msg.MsgType) { case MessageType.CONNACK: { MqConnack cm=msg as MqConnack; if(cm.Response!=MqConnack.MqttConnectionResponse.Accepted) { Reconnect(true); Log.Error("Connection to {0}:{1} failed. error={2}", addr, port, cm.Response.ToString()); } else { _connected=true; _subs.Clear(); Topic_SubscriptionsChg(null, true); } if(StatusChg!=null) { StatusChg(_connected); } } break; case MessageType.DISCONNECT: Reconnect(); break; case MessageType.PINGRESP: _waitPingResp=false; break; case MessageType.PUBLISH: { MqPublish pm=msg as MqPublish; if(msg.MessageID!=0) { if(msg.QualityOfService==QoS.AtLeastOnce) { this.Send(new MqMsgAck(MessageType.PUBACK, msg.MessageID)); } else if(msg.QualityOfService==QoS.ExactlyOnce) { this.Send(new MqMsgAck(MessageType.PUBREC, msg.MessageID)); } } ProccessPublishMsg(pm); } break; case MessageType.PUBACK: break; case MessageType.PUBREC: if(msg.MessageID!=0) { this.Send(new MqMsgAck(MessageType.PUBREL, msg.MessageID)); } break; case MessageType.PUBREL: if(msg.MessageID!=0) { this.Send(new MqMsgAck(MessageType.PUBCOMP, msg.MessageID)); } break; case MessageType.PUBCOMP: break; default: break; } if(_waitPingResp) { _tOut.Change(_keepAliveMS, _keepAliveMS); } }
public wMessage(MqMessage msg) { this.msg = msg; this.cnt = 0; }
private void RcvProcess(IAsyncResult ar) { bool first = true; int len; try { len = _stream.EndRead(ar); } catch (IOException) { Close(true); return; } catch (ObjectDisposedException) { return; } if (len > 0) { try { do { if (first) { first = false; } else { _rcvBuf[0] = (byte)_stream.ReadByte(); } switch (_rcvState) { case 0: // header _rcvHeader = _rcvBuf[0]; _rcvLengt = 0; _rcvLengthPos = 0; _rcvState++; break; case 1: { _rcvLengt += (uint)((_rcvBuf[0] & 0x7F) << (7 * _rcvLengthPos)); _rcvLengthPos++; if ((_rcvBuf[0] & 0x80) == 0) { _rcvState++; _rcvLengthPos = 0; if (_rcvLengt == 0) { goto case 2; } } } break; case 2: if (_rcvMemoryStream.Position < _rcvLengt) { _rcvMemoryStream.WriteByte(_rcvBuf[0]); } if (_rcvMemoryStream.Position >= _rcvLengt) { _rcvMemoryStream.Seek(0, SeekOrigin.Begin); MqMessage msg = MqMessage.Parse(_rcvHeader, _rcvLengt, _rcvMemoryStream); if (msg == null) { Log.Warning("unrecognized message from {0}={1:X2}[{2}]", ((IPEndPoint)Socket.Client.RemoteEndPoint), _rcvHeader, _rcvLengt); _rcvMemoryStream.Seek(0, SeekOrigin.Begin); _rcvState = 0; } else { _rcvMemoryStream.Seek(0, SeekOrigin.Begin); _rcvMemoryStream.SetLength(0); _rcvState = 0; if (msg.MessageID != 0) { if (msg.Reason != MessageType.NONE) { _waitAck.RemoveAll(wm => wm.msg.MessageID == msg.MessageID && wm.msg.MsgType == msg.Reason); } else { int nid = msg.MessageID + 1; if (nid == 0x10000) { nid++; } if (nid > (int)_messageIdGen || (nid > 0xFF00 && _messageIdGen < 0x0100)) { _messageIdGen = (ushort)nid; // synchronize messageId } } } if (_rcvCallback != null) { _rcvCallback(msg); } } if (_waitAck.Count > 0) { _sendTimer.Change(900, Timeout.Infinite); // connection is busy } } break; default: _rcvState = 0; break; } } while(_stream.DataAvailable); if (_rcvState != 0) { _rcvTimer.Change(100, Timeout.Infinite); } else { _rcvTimer.Change(Timeout.Infinite, Timeout.Infinite); } } catch (ObjectDisposedException) { return; } catch (ArgumentException ex) { _rcvMemoryStream.Seek(0, SeekOrigin.Begin); _rcvState = 0; Log.Warning(ex.Message); } catch (Exception ex) { _rcvMemoryStream.Seek(0, SeekOrigin.Begin); _rcvState = 0; Log.Warning(ex.ToString()); } } else { if (_connected) { this.Close(true); } return; } try { _stream.BeginRead(_rcvBuf, 0, 1, RcvProcess, _stream); } catch (IOException ex) { if (_connected) { this.Close(true); Log.Warning("MqStreamer.RcvProcess {0}", ex.Message); } return; } catch (ObjectDisposedException ex) { Log.Warning("MqStreamer.RcvProcess {0}", ex.Message); return; } }
private void Received(MqMessage msg) { if (_pl.verbose) { Log.Debug("R {0} > {1}", this.Signature, msg); } switch (msg.MsgType) { case MessageType.CONNACK: { MqConnack cm = msg as MqConnack; if (cm.Response == MqConnack.MqttConnectionResponse.Accepted) { status = Status.Connected; _tOut.Change(KEEP_ALIVE, KEEP_ALIVE); Log.Info("Connected to {0}", Signature); foreach (var site in Sites) { site.Connected(); } } else { status = Status.NotAccepted; _tOut.Change(Timeout.Infinite, Timeout.Infinite); } } break; case MessageType.DISCONNECT: status = Status.Disconnected; _tOut.Change(3000, KEEP_ALIVE); break; case MessageType.PINGRESP: _waitPingResp = false; break; case MessageType.PUBLISH: { MqPublish pm = msg as MqPublish; if (msg.MessageID != 0) { if (msg.QualityOfService == QoS.AtLeastOnce) { this.Send(new MqMsgAck(MessageType.PUBACK, msg.MessageID)); } else if (msg.QualityOfService == QoS.ExactlyOnce) { this.Send(new MqMsgAck(MessageType.PUBREC, msg.MessageID)); } } ProccessPublishMsg(pm); } break; case MessageType.PUBACK: break; case MessageType.PUBREC: if (msg.MessageID != 0) { this.Send(new MqMsgAck(MessageType.PUBREL, msg.MessageID)); } break; case MessageType.PUBREL: if (msg.MessageID != 0) { this.Send(new MqMsgAck(MessageType.PUBCOMP, msg.MessageID)); } break; } if (_waitPingResp) { _tOut.Change(KEEP_ALIVE, KEEP_ALIVE); } }
public wMessage(MqMessage msg) { this.msg=msg; this.cnt=0; }
private void SendIntern(MqMessage msg) { if(msg==null || _waitAck==null) { return; } MemoryStream ms=new MemoryStream(); msg.Serialise(ms); try { _stream.BeginWrite(ms.GetBuffer(), 0, (int)ms.Length, _sendCB, null); } catch(IOException) { if(this._connected) { this.Close(); } return; } catch(ObjectDisposedException) { return; } catch(Exception ex) { string re; try{ re=Socket.Client.RemoteEndPoint.ToString(); }catch(Exception){ re="UNK"; } Log.Warning("MqStreamer.SendIntern({0}, {1}) - {2}", msg.ToString(), re, ex.ToString()); } if(msg.QualityOfService!=QoS.AtMostOnce && !msg.Duplicate) { _waitAck.Add(new wMessage(msg)); } msg.Duplicate=true; if(msg.MsgType==MessageType.DISCONNECT) { Thread.Sleep(30); // hack, wait fo buffers flush Close(true); } }