/// <summary> /// Transmits the message via the UDP broadcast client. /// </summary> /// <param name="toEP">The target endpoint.</param> /// <param name="msg">The message.</param> private void TransmitViaUdpBroadcast(ChannelEP toEP, Msg msg) { byte[] sendBuf; int cbSend; int cbMsg; msg._SetToChannel(toEP); msg._SetFromChannel(localEP); msg._Trace(router, 2, "UDP: Send", null); using (TimedLock.Lock(router.SyncRoot)) { // Initiate transmission of the message cbMsg = Msg.Save(new EnhancedMemoryStream(msgBuf), msg); sendBuf = router.EncryptFrame(msgBuf, cbMsg); cbSend = sendBuf.Length; Assertion.Validate(cbSend <= TcpConst.MTU - UdpBroadcastClient.MessageEnvelopeSize, "Message larger than UDP MTU."); try { broadcastClient.Broadcast(sendBuf); } catch { } } }
/// <summary> /// Constuctor. /// </summary> /// <param name="operation">Specifies how the message should be interpreted.</param> /// <param name="timestamp">The time (UTC) when the delivery was completed successfully or was aborted.</param> /// <param name="targetEP">The original target or cluster endpoint.</param> /// <param name="confirmEP">The confirmation endpoint (or <c>null</c>).</param> /// <param name="query">The query message.</param> /// <param name="topologyID">The globally unique cluster topology provider instance ID or <see cref="Guid.Empty" />.</param> /// <param name="topologyInfo">The serialized cluster itopology nformation (or <c>null</c>).</param> /// <param name="topologyParam">The serialized topology parameter (or <c>null</c>).</param> /// <param name="exception">The exception for failed deliveries or queries.</param> /// <param name="response">The response message (or <c>null</c>).</param> public DeliveryMsg(DeliveryOperation operation, DateTime timestamp, MsgEP targetEP, MsgEP confirmEP, Msg query, Guid topologyID, string topologyInfo, string topologyParam, Exception exception, Msg response) { this.Operation = operation; this.Timestamp = timestamp; this.TargetEP = targetEP; this.ConfirmEP = confirmEP; this.TopologyID = topologyID; this.TopologyInfo = topologyInfo; this.TopologyParam = topologyParam; this.Exception = exception; this.query = query; this.response = response; // Serialize the query and responses to the message blob EnhancedBlockStream es = new EnhancedBlockStream(); try { Msg.Save(es, query); if (response != null) { Msg.Save(es, response); } base._Data = es.ToArray(); } finally { es.Close(); } }
/// <summary> /// Serializes the message and save the result to the message's /// <see cref="Msg._MsgFrame" /> property. /// </summary> /// <param name="msg">The message to be serialized.</param> private void Serialize(Msg msg) { var ms = new EnhancedMemoryStream(DefMsgSize); int cbMsg; cbMsg = Msg.Save(ms, msg); msg._MsgFrame = router.EncryptFrame(ms.GetBuffer(), cbMsg); }
/// <summary> /// Generates a clone of this message instance, generating a new /// <see cref="_MsgID" /> property if the original ID is /// not empty. /// </summary> /// <returns>Returns a clone of the message.</returns> /// <remarks> /// <para> /// This base method works by serializing and then deseralizing a new copy of /// the message to a buffer and then generating a new <see cref="_MsgID" /> GUID. This /// implementation will be relatively costly in terms of processor and /// memory resources. /// </para> /// <para> /// Derived messages can choose to override this and implement a shallow /// clone instead, using the <see cref="CopyBaseFields" /> method. Note that /// the <see cref="CopyBaseFields" /> method ensures that a new <see cref="_MsgID" /> /// property is regenerated if the original ID field is not empty. /// </para> /// </remarks> public virtual Msg Clone() { var es = new EnhancedBlockStream(1024, 1024); Msg clone; Msg.Save(es, this); es.Position = 0; clone = Msg.Load(es); if (this.msgID != Guid.Empty) { clone.msgID = Helper.NewGuid(); } return(clone); }
/// <summary> /// Handles message packet send completions on the socket. /// </summary> /// <param name="ar">The async result.</param> private void OnSend(IAsyncResult ar) { ChannelEP toEP; int cb; int cbMsg; using (TimedLock.Lock(router.SyncRoot)) { if (!isOpen || sendMsg == null) { return; } Assertion.Test(sendMsg != null); sendMsg = null; try { cb = sock.EndSendTo(ar); Assertion.Test(cb == cbSend); if (sendQueue.Count > 0) { sendMsg = sendQueue.Dequeue(); toEP = sendMsg._ToEP.ChannelEP; sendMsg._SetFromChannel(localEP); cbMsg = Msg.Save(new EnhancedMemoryStream(msgBuf), sendMsg); sendBuf = router.EncryptFrame(msgBuf, cbMsg); cbSend = sendBuf.Length; Assertion.Validate(cbSend <= TcpConst.MTU, "Message larger than UDP MTU."); sock.BeginSendTo(sendBuf, 0, cbSend, SocketFlags.None, router.NormalizeEP(toEP.NetEP), onSend, null); } } catch { } } }
/// <summary> /// Transmits the message via the socket. /// </summary> /// <param name="toEP">The target endpoint.</param> /// <param name="msg">The message.</param> private void TransmitViaSocket(ChannelEP toEP, Msg msg) { int cbMsg; if (cloudEP != null && !multicastInit) { // Retry adding the socket to the multicast group if this didn't // work earlier. try { this.sock.MulticastGroup = cloudEP.Address; this.multicastInit = true; } catch { this.multicastInit = false; } } msg._SetToChannel(toEP); msg._SetFromChannel(localEP); msg._Trace(router, 2, "UDP: Send", null); using (TimedLock.Lock(router.SyncRoot)) { if (sendMsg != null) { // We're already in the process of transmitting // a message so queue this one. Enqueue(msg); return; } // If there are already messages in the queue then queue // this one and then setup to transmit the first message // waiting in the queue. if (sendQueue.Count > 0) { Enqueue(msg); msg = sendQueue.Dequeue(); } // Initiate transmission of the message sendMsg = msg; cbMsg = Msg.Save(new EnhancedMemoryStream(msgBuf), sendMsg); sendBuf = router.EncryptFrame(msgBuf, cbMsg); cbSend = sendBuf.Length; Assertion.Validate(cbSend <= TcpConst.MTU, "Message larger than UDP MTU."); try { sock.BeginSendTo(sendBuf, 0, cbSend, SocketFlags.None, router.NormalizeEP(toEP.NetEP), onSend, null); } catch { // Ignoring } } }