public void Connect([NotNull] string addr)
{
CheckContextTerminated();
// Process pending commands, if any.
ProcessCommands(0, false);
string address;
string protocol;
DecodeAddress(addr, out address, out protocol);
CheckProtocol(protocol);
if (protocol == Address.InProcProtocol)
{
// TODO: inproc connect is specific with respect to creating pipes
// as there's no 'reconnect' functionality implemented. Once that
// is in place we should follow generic pipe creation algorithm.
// Find the peer endpoint.
Ctx.Endpoint peer = FindEndpoint(addr);
// The total HWM for an inproc connection should be the sum of
// the binder's HWM and the connector's HWM.
var sndhwm = m_options.SendHighWatermark != 0 && peer.Options.ReceiveHighWatermark != 0
? m_options.SendHighWatermark + peer.Options.ReceiveHighWatermark
: 0;
var rcvhwm = m_options.ReceiveHighWatermark != 0 && peer.Options.SendHighWatermark != 0
? m_options.ReceiveHighWatermark + peer.Options.SendHighWatermark
: 0;
// Create a bi-directional pipe to connect the peers.
ZObject[] parents = { this, peer.Socket };
int[] highWaterMarks = { sndhwm, rcvhwm };
bool[] delays = { m_options.DelayOnDisconnect, m_options.DelayOnClose };
Pipe[] pipes = Pipe.PipePair(parents, highWaterMarks, delays);
// Attach local end of the pipe to this socket object.
AttachPipe(pipes[0]);
// If required, send the identity of the local socket to the peer.
if (peer.Options.RecvIdentity)
{
var id = new Msg();
id.InitPool(m_options.IdentitySize);
id.Put(m_options.Identity, 0, m_options.IdentitySize);
id.SetFlags(MsgFlags.Identity);
bool written = pipes[0].Write(ref id);
Debug.Assert(written);
pipes[0].Flush();
}
// If required, send the identity of the peer to the local socket.
if (m_options.RecvIdentity)
{
var id = new Msg();
id.InitPool(peer.Options.IdentitySize);
id.Put(peer.Options.Identity, 0, peer.Options.IdentitySize);
id.SetFlags(MsgFlags.Identity);
bool written = pipes[1].Write(ref id);
Debug.Assert(written);
pipes[1].Flush();
}
// Attach remote end of the pipe to the peer socket. Note that peer's
// seqnum was incremented in find_endpoint function. We don't need it
// increased here.
SendBind(peer.Socket, pipes[1], false);
// Save last endpoint URI
m_options.LastEndpoint = addr;
// remember inproc connections for disconnect
m_inprocs.Add(addr, pipes[0]);
return;
}
// Choose the I/O thread to run the session in.
var ioThread = ChooseIOThread(m_options.Affinity);
if (ioThread == null)
throw NetMQException.Create(ErrorCode.EmptyThread);
var paddr = new Address(protocol, address);
// Resolve address (if needed by the protocol)
switch (protocol)
{
case Address.TcpProtocol:
{
paddr.Resolved = (new TcpAddress());
paddr.Resolved.Resolve(address, m_options.IPv4Only);
break;
}
case Address.IpcProtocol:
{
paddr.Resolved = (new IpcAddress());
paddr.Resolved.Resolve(address, true);
break;
}
case Address.PgmProtocol:
case Address.EpgmProtocol:
{
if (m_options.SocketType == ZmqSocketType.Sub || m_options.SocketType == ZmqSocketType.Xsub)
{
Bind(addr);
return;
}
paddr.Resolved = new PgmAddress();
paddr.Resolved.Resolve(address, m_options.IPv4Only);
break;
}
}
// Create session.
SessionBase session = SessionBase.Create(ioThread, true, this, m_options, paddr);
Debug.Assert(session != null);
// PGM does not support subscription forwarding; ask for all data to be
// sent to this pipe.
bool icanhasall = protocol == Address.PgmProtocol || protocol == Address.EpgmProtocol;
Pipe newPipe = null;
if (!m_options.DelayAttachOnConnect || icanhasall)
{
// Create a bi-directional pipe.
ZObject[] parents = { this, session };
int[] hwms = { m_options.SendHighWatermark, m_options.ReceiveHighWatermark };
bool[] delays = { m_options.DelayOnDisconnect, m_options.DelayOnClose };
Pipe[] pipes = Pipe.PipePair(parents, hwms, delays);
// Attach local end of the pipe to the socket object.
AttachPipe(pipes[0], icanhasall);
newPipe = pipes[0];
// Attach remote end of the pipe to the session object later on.
session.AttachPipe(pipes[1]);
}
// Save last endpoint URI
m_options.LastEndpoint = paddr.ToString();
AddEndpoint(addr, session, newPipe);
}