public void Move(ref Msg src) { // Check the validity of the source. if (!src.Check()) { throw NetMQException.Create(ErrorCode.EFAULT); } Close(); this = src; src.InitEmpty(); }
public XSub(Ctx parent, int threadId, int sid) : base(parent, threadId, sid) { m_options.SocketType = ZmqSocketType.Xsub; m_hasMessage = false; m_more = false; m_options.Linger = 0; m_fq = new FQ(); m_dist = new Dist(); m_subscriptions = new Trie(); m_message = new Msg(); m_message.InitEmpty(); }
public virtual bool PushMsg(ref Msg msg) { // First message to receive is identity (if required). if (!m_identityReceived) { msg.SetFlags(MsgFlags.Identity); m_identityReceived = true; if (!m_options.RecvIdentity) { msg.Close(); msg.InitEmpty(); return(true); } } if (m_pipe != null && m_pipe.Write(ref msg)) { msg.InitEmpty(); return(true); } return(false); }
public virtual void PushMsg(ref Msg msg) { // First message to receive is identity (if required). if (!m_identityReceived) { msg.SetFlags(MsgFlags.Identity); m_identityReceived = true; if (!m_options.RecvIdentity) { msg.Close(); msg.InitEmpty(); return; } } if (m_pipe != null && m_pipe.Write(ref msg)) { msg.InitEmpty(); return; } throw AgainException.Create(); }
public bool RecvPipe(Pipe[] pipe, ref Msg msg) { // Deallocate old content of the message. msg.Close(); // Round-robin over the pipes to get the next message. while (m_active > 0) { // Try to fetch new message. If we've already read part of the message // subsequent part should be immediately available. bool fetched = m_pipes[m_current].Read(ref msg); // Note that when message is not fetched, current pipe is deactivated // and replaced by another active pipe. Thus we don't have to increase // the 'current' pointer. if (fetched) { if (pipe != null) { pipe[0] = m_pipes[m_current]; } m_more = msg.HasMore; if (!m_more) { m_current = (m_current + 1) % m_active; } return(true); } // Check the atomicity of the message. // If we've already received the first part of the message // we should get the remaining parts without blocking. Debug.Assert(!m_more); m_active--; Utils.Swap(m_pipes, m_current, m_active); if (m_current == m_active) { m_current = 0; } } // No message is available. Initialise the output parameter // to be a 0-byte message. msg.InitEmpty(); return(false); }
protected bool XSend(ref Msg msg, SendReceiveOptions flags) { if (m_pipe == null || !m_pipe.Write(ref msg)) { return(false); } if ((flags & SendReceiveOptions.SendMore) == 0) { m_pipe.Flush(); } // Detach the original message from the data buffer. msg.InitEmpty(); return(true); }
public static MonitorEvent Read([NotNull] SocketBase s) { var msg = new Msg(); msg.InitEmpty(); s.Recv(ref msg, SendReceiveOptions.None); int pos = 0; ByteArraySegment data = msg.Data; var @event = (SocketEvent)data.GetInteger(Endianness.Little, pos); pos += 4; var len = (int)data[pos++]; string addr = data.GetString(len, pos); pos += len; var flag = (int)data[pos++]; Object arg = null; if (flag == ValueInteger) { arg = data.GetInteger(Endianness.Little, pos); } else if (flag == ValueChannel) { IntPtr value = s_sizeOfIntPtr == 4 ? new IntPtr(data.GetInteger(Endianness.Little, pos)) : new IntPtr(data.GetLong(Endianness.Little, pos)); GCHandle handle = GCHandle.FromIntPtr(value); AsyncSocket socket = null; if (handle.IsAllocated) { socket = handle.Target as AsyncSocket; } handle.Free(); arg = socket; } return(new MonitorEvent(@event, addr, arg)); }
protected override bool XSend(ref Msg msg, SendReceiveOptions flags) { // If we've sent a request and we still haven't got the reply, // we can't send another request. if (m_receivingReply) { throw NetMQException.Create("Cannot send another request", ErrorCode.EFSM); } bool isMessageSent; // First part of the request is the request identity. if (m_messageBegins) { Msg bottom = new Msg(); bottom.InitEmpty(); bottom.SetFlags(MsgFlags.More); isMessageSent = base.XSend(ref bottom, 0); if (!isMessageSent) { return(false); } m_messageBegins = false; } bool more = msg.HasMore; isMessageSent = base.XSend(ref msg, flags); if (!isMessageSent) { return(false); } // If the request was fully sent, flip the FSM into reply-receiving state. else if (!more) { m_receivingReply = true; m_messageBegins = true; } return(true); }
// Holds the prefetched message. public Dealer(Ctx parent, int threadId, int sid) : base(parent, threadId, sid) { m_prefetched = false; m_options.SocketType = ZmqSocketType.Dealer; m_fq = new FQ(); m_lb = new LB(); // TODO: Uncomment the following line when DEALER will become true DEALER // rather than generic dealer socket. // If the socket is closing we can drop all the outbound requests. There'll // be noone to receive the replies anyway. // options.delay_on_close = false; m_options.RecvIdentity = true; m_prefetchedMsg = new Msg(); m_prefetchedMsg.InitEmpty(); }
public void Plug(IOThread ioThread, SessionBase session) { m_encoder.SetMsgSource(session); AddFd(m_socket); SetPollout(m_socket); // get the first message from the session because we don't want to send identities Msg msg = new Msg(); msg.InitEmpty(); bool ok = session.PullMsg(ref msg); if (ok) { msg.Close(); } }
public void Plug(IOThread ioThread, SessionBase session) { m_session = session; m_socket = session.Socket; m_ioObject = new IOObject(null); m_ioObject.SetHandler(this); m_ioObject.Plug(ioThread); m_ioObject.AddFd(m_handle); m_ioObject.SetPollin(m_handle); DropSubscriptions(); var msg = new Msg(); msg.InitEmpty(); // push message to the session because there is no identity message with pgm session.PushMsg(ref msg); }
public Stream(Ctx parent, int threadId, int sid) : base(parent, threadId, sid) { m_prefetched = false; m_identitySent = false; m_currentOut = null; m_moreOut = false; m_nextPeerId = Utils.GenerateRandom(); m_options.SocketType = ZmqSocketType.Stream; m_fq = new FQ(); m_prefetchedId = new Msg(); m_prefetchedId.InitEmpty(); m_prefetchedMsg = new Msg(); m_prefetchedMsg.InitEmpty(); m_outpipes = new Dictionary <Blob, Outpipe>(); m_options.RawSocket = true; }
// Remove any half processed messages. Flush unflushed messages. // Call this function when engine disconnect to get rid of leftovers. private void CleanPipes() { if (m_pipe != null) { // Get rid of half-processed messages in the out pipe. Flush any // unflushed messages upstream. m_pipe.Rollback(); m_pipe.Flush(); // Remove any half-read message from the in pipe. while (m_incompleteIn) { Msg msg = new Msg(); msg.InitEmpty(); if (!PullMsg(ref msg)) { Debug.Assert(!m_incompleteIn); break; } msg.Close(); } } }
public static bool CreateProxy(SocketBase frontend, SocketBase backend, SocketBase capture) { // The algorithm below assumes ratio of requests and replies processed // under full load to be 1:1. int more; int rc; Msg msg = new Msg(); msg.InitEmpty(); PollItem[] items = new PollItem[2]; items[0] = new PollItem(frontend, PollEvents.PollIn); items[1] = new PollItem(backend, PollEvents.PollIn); while (true) { // Wait while there are either requests or replies to process. rc = ZMQ.Poll(items, -1); if (rc < 0) { return(false); } // Process a request. if ((items[0].ResultEvent & PollEvents.PollIn) == PollEvents.PollIn) { while (true) { try { frontend.Recv(ref msg, SendReceiveOptions.None); } catch (TerminatingException) { return(false); } more = frontend.GetSocketOption(ZmqSocketOptions.ReceiveMore); if (more < 0) { return(false); } // Copy message to capture socket if any if (capture != null) { Msg ctrl = new Msg(); ctrl.InitEmpty(); ctrl.Copy(ref msg); capture.Send(ref ctrl, more > 0 ? SendReceiveOptions.SendMore : 0); } backend.Send(ref msg, more > 0 ? SendReceiveOptions.SendMore : 0); if (more == 0) { break; } } } // Process a reply. if ((items[1].ResultEvent & PollEvents.PollIn) == PollEvents.PollIn) { while (true) { try { backend.Recv(ref msg, SendReceiveOptions.None); } catch (TerminatingException) { return(false); } more = backend.GetSocketOption(ZmqSocketOptions.ReceiveMore); if (more < 0) { return(false); } // Copy message to capture socket if any if (capture != null) { Msg ctrl = new Msg(); ctrl.InitEmpty(); ctrl.Copy(ref msg); capture.Send(ref ctrl, more > 0 ? SendReceiveOptions.SendMore : 0); } frontend.Send(ref msg, more > 0 ? SendReceiveOptions.SendMore : 0); if (more == 0) { break; } } } } }
public virtual bool PushMsg(ref Msg msg) { // First message to receive is identity (if required). if (!m_identityReceived) { msg.SetFlags(MsgFlags.Identity); m_identityReceived = true; if (!m_options.RecvIdentity) { msg.Close(); msg.InitEmpty(); return true; } } if (m_pipe != null && m_pipe.Write(ref msg)) { msg.InitEmpty(); return true; } return false; }
public static MonitorEvent Read([NotNull] SocketBase s) { var msg = new Msg(); msg.InitEmpty(); s.Recv(ref msg, SendReceiveOptions.None); int pos = 0; ByteArraySegment data = msg.Data; var @event = (SocketEvent)data.GetInteger(Endianness.Little, pos); pos += 4; var len = (int)data[pos++]; string addr = data.GetString(len, pos); pos += len; var flag = (int)data[pos++]; Object arg = null; if (flag == ValueInteger) { arg = data.GetInteger(Endianness.Little, pos); } else if (flag == ValueChannel) { IntPtr value = s_sizeOfIntPtr == 4 ? new IntPtr(data.GetInteger(Endianness.Little, pos)) : new IntPtr(data.GetLong(Endianness.Little, pos)); GCHandle handle = GCHandle.FromIntPtr(value); AsyncSocket socket = null; if (handle.IsAllocated) { socket = handle.Target as AsyncSocket; } handle.Free(); arg = socket; } return new MonitorEvent(@event, addr, arg); }
protected override bool XSend(ref Msg msg, SendReceiveOptions flags) { // If this is the first part of the message it's the ID of the // peer to send the message to. if (!m_moreOut) { Debug.Assert(m_currentOut == null); // If we have malformed message (prefix with no subsequent message) // then just silently ignore it. // TODO: The connections should be killed instead. if (msg.HasMore) { m_moreOut = true; // Find the pipe associated with the identity stored in the prefix. // If there's no such pipe just silently ignore the message, unless // mandatory is set. Blob identity = new Blob(msg.Data, msg.Size); Outpipe op; if (m_outpipes.TryGetValue(identity, out op)) { m_currentOut = op.Pipe; if (!m_currentOut.CheckWrite()) { op.Active = false; m_currentOut = null; if (m_mandatory) { m_moreOut = false; return(false); } } } else if (m_mandatory) { m_moreOut = false; throw NetMQException.Create(ErrorCode.EHOSTUNREACH); } } // Detach the message from the data buffer. msg.Close(); msg.InitEmpty(); return(true); } if (m_options.RawSocket) { msg.ResetFlags(MsgFlags.More); } // Check whether this is the last part of the message. m_moreOut = msg.HasMore; // Push the message into the pipe. If there's no out pipe, just drop it. if (m_currentOut != null) { // Close the remote connection if user has asked to do so // by sending zero length message. // Pending messages in the pipe will be dropped (on receiving term- ack) if (m_rawSocket && msg.Size == 0) { m_currentOut.Terminate(false); msg.Close(); msg.InitEmpty(); m_currentOut = null; return(true); } bool ok = m_currentOut.Write(ref msg); if (!ok) { m_currentOut = null; } else if (!m_moreOut) { m_currentOut.Flush(); m_currentOut = null; } } else { msg.Close(); } // Detach the message from the data buffer. msg.InitEmpty(); return(true); }
private bool IdentifyPeer(Pipe pipe) { Blob identity; if (m_options.RawSocket) { // Always assign identity for raw-socket byte[] buf = new byte[5]; buf[0] = 0; byte[] result = BitConverter.GetBytes(m_nextPeerId++); Buffer.BlockCopy(result, 0, buf, 1, 4); identity = new Blob(buf, buf.Length); } else { // Pick up handshake cases and also case where next identity is set Msg msg = new Msg(); msg.InitEmpty(); bool ok = pipe.Read(ref msg); if (!ok) { return(false); } if (msg.Size == 0) { // Fall back on the auto-generation byte[] buf = new byte[5]; buf[0] = 0; byte[] result = BitConverter.GetBytes(m_nextPeerId++); Buffer.BlockCopy(result, 0, buf, 1, 4); identity = new Blob(buf, buf.Length); msg.Close(); } else { identity = new Blob(msg.Data, msg.Size); // Ignore peers with duplicate ID. if (m_outpipes.ContainsKey(identity)) { msg.Close(); return(false); } msg.Close(); } } pipe.Identity = identity; // Add the record into output pipes lookup table Outpipe outpipe = new Outpipe(pipe, true); m_outpipes.Add(identity, outpipe); return(true); }
protected override void Consume(PullSocket socket, int messageSize) { var msg = new Msg(); msg.InitEmpty(); for (int i = 0; i < MsgCount; i++) { socket.Receive(ref msg, SendReceiveOptions.None); Debug.Assert(msg.Data.Length == messageSize, "Message length was different from expected size."); Debug.Assert(msg.Data[msg.Size/2] == 0x42, "Message did not contain verification data."); } }
// Remove any half processed messages. Flush unflushed messages. // Call this function when engine disconnect to get rid of leftovers. private void CleanPipes() { if (m_pipe != null) { // Get rid of half-processed messages in the out pipe. Flush any // unflushed messages upstream. m_pipe.Rollback(); m_pipe.Flush(); // Remove any half-read message from the in pipe. while (m_incompleteIn) { var msg = new Msg(); msg.InitEmpty(); if (!PullMsg(ref msg)) { Debug.Assert(!m_incompleteIn); break; } msg.Close(); } } }