use of zmq.io.net.NetProtocol in project jeromq by zeromq.
the class SocketBase method monitor.
/**
* Register the address for a monitor. It must be a inproc PAIR.
* @param addr or null for unregister.
* @param events an event mask to monitor.
* @return true if creation succeeded.
* @throws IllegalStateException if a previous monitor was already
* registered.
*/
public final boolean monitor(final String addr, int events) {
try {
monitorSync.lock();
boolean rc;
if (ctxTerminated) {
errno.set(ZError.ETERM);
return false;
}
// Support deregistering monitoring endpoints as well
if (addr == null) {
stopMonitor();
return true;
}
if (monitorSocket != null) {
throw new IllegalStateException("Monitor registred twice");
}
SimpleURI uri = SimpleURI.create(addr);
NetProtocol protocol = checkProtocol(uri.getProtocol());
if (protocol == null) {
return false;
}
// Event notification only supported over inproc://
if (protocol != NetProtocol.inproc) {
errno.set(ZError.EPROTONOSUPPORT);
return false;
}
// Register events to monitor
monitorEvents = events;
monitorSocket = getCtx().createSocket(ZMQ.ZMQ_PAIR);
if (monitorSocket == null) {
return false;
}
// Never block context termination on pending event messages
try {
monitorSocket.setSocketOpt(ZMQ.ZMQ_LINGER, 0);
} catch (IllegalArgumentException e) {
stopMonitor();
throw e;
}
// Spawn the monitor socket endpoint
rc = monitorSocket.bind(addr);
if (!rc) {
stopMonitor();
}
return rc;
} finally {
monitorSync.unlock();
}
}
use of zmq.io.net.NetProtocol in project jeromq by zeromq.
the class SocketBase method bind.
public final boolean bind(final String addr) {
lock();
try {
if (ctxTerminated) {
errno.set(ZError.ETERM);
return false;
}
options.mechanism.check(options);
// Process pending commands, if any.
boolean brc = processCommands(0, false, null);
if (!brc) {
return false;
}
SimpleURI uri = SimpleURI.create(addr);
String address = uri.getAddress();
NetProtocol protocol = checkProtocol(uri.getProtocol());
if (protocol == null) {
return false;
}
switch(protocol) {
case inproc:
{
Ctx.Endpoint endpoint = new Ctx.Endpoint(this, options);
boolean rc = registerEndpoint(addr, endpoint);
if (rc) {
connectPending(addr, this);
// Save last endpoint URI
options.lastEndpoint = addr;
} else {
errno.set(ZError.EADDRINUSE);
}
return rc;
}
case pgm:
// continue
case epgm:
// continue
case norm:
// connect for PGM, EPGM and NORM transports.
return connect(addr);
case tcp:
// continue
case ipc:
// continue
case tipc:
{
// Remaining transports require to be run in an I/O thread, so at this
// point we'll choose one.
IOThread ioThread = chooseIoThread(options.affinity);
if (ioThread == null) {
errno.set(ZError.EMTHREAD);
return false;
}
Listener listener = protocol.getListener(ioThread, this, options);
boolean rc = listener.setAddress(address);
if (!rc) {
listener.destroy();
eventBindFailed(address, errno.get());
return false;
}
// Save last endpoint URI
options.lastEndpoint = listener.getAddress();
addEndpoint(options.lastEndpoint, listener, null);
return true;
}
default:
throw new IllegalArgumentException(addr);
}
} finally {
unlock();
}
}
use of zmq.io.net.NetProtocol in project jeromq by zeromq.
the class SocketBase method connectInternal.
private boolean connectInternal(String addr) {
if (ctxTerminated) {
errno.set(ZError.ETERM);
return false;
}
options.mechanism.check(options);
// Process pending commands, if any.
boolean brc = processCommands(0, false, null);
if (!brc) {
return false;
}
SimpleURI uri = SimpleURI.create(addr);
String address = uri.getAddress();
NetProtocol protocol = checkProtocol(uri.getProtocol());
if (protocol == null || !protocol.valid) {
return false;
}
if (protocol == NetProtocol.inproc) {
// 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.
int sndhwm = 0;
if (peer.socket == null) {
sndhwm = options.sendHwm;
} else if (options.sendHwm != 0 && peer.options.recvHwm != 0) {
sndhwm = options.sendHwm + peer.options.recvHwm;
}
int rcvhwm = 0;
if (peer.socket == null) {
rcvhwm = options.recvHwm;
} else if (options.recvHwm != 0 && peer.options.sendHwm != 0) {
rcvhwm = options.recvHwm + peer.options.sendHwm;
}
// Create a bi-directional pipe to connect the peers.
ZObject[] parents = { this, peer.socket == null ? this : peer.socket };
boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
int[] hwms = { conflate ? -1 : sndhwm, conflate ? -1 : rcvhwm };
boolean[] conflates = { conflate, conflate };
Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
// Attach local end of the pipe to this socket object.
attachPipe(pipes[0], true);
if (peer.socket == null) {
// The peer doesn't exist yet so we don't know whether
// to send the identity message or not. To resolve this,
// we always send our identity and drop it later if
// the peer doesn't expect it.
Msg id = new Msg(options.identitySize);
id.put(options.identity, 0, options.identitySize);
id.setFlags(Msg.IDENTITY);
boolean written = pipes[0].write(id);
assert (written);
pipes[0].flush();
// If set, send the hello msg of the local socket to the peer.
if (options.canSendHelloMsg && options.helloMsg != null) {
written = pipes[0].write(options.helloMsg);
assert (written);
pipes[0].flush();
}
pendConnection(addr, new Ctx.Endpoint(this, options), pipes);
} else {
// If required, send the identity of the peer to the local socket.
if (peer.options.recvIdentity) {
Msg id = new Msg(options.identitySize);
id.put(options.identity, 0, options.identitySize);
id.setFlags(Msg.IDENTITY);
boolean written = pipes[0].write(id);
assert (written);
pipes[0].flush();
}
// If required, send the identity of the local socket to the peer.
if (options.recvIdentity) {
Msg id = new Msg(peer.options.identitySize);
id.put(peer.options.identity, 0, peer.options.identitySize);
id.setFlags(Msg.IDENTITY);
boolean written = pipes[1].write(id);
assert (written);
pipes[1].flush();
}
// If set, send the hello msg of the local socket to the peer.
if (options.canSendHelloMsg && options.helloMsg != null) {
boolean written = pipes[0].write(options.helloMsg);
assert (written);
pipes[0].flush();
}
// If set, send the hello msg of the peer to the local socket.
if (peer.options.canSendHelloMsg && peer.options.helloMsg != null) {
boolean written = pipes[1].write(peer.options.helloMsg);
assert (written);
pipes[1].flush();
}
if (peer.options.canReceiveDisconnectMsg && peer.options.disconnectMsg != null) {
pipes[0].setDisconnectMsg(peer.options.disconnectMsg);
}
// Attach remote end of the pipe to the peer socket. Note that peer's
// seqnum was incremented in findEndpoint function. We don't need it
// increased here.
sendBind(peer.socket, pipes[1], false);
}
// Save last endpoint URI
options.lastEndpoint = addr;
// remember inproc connections for disconnect
inprocs.insert(addr, pipes[0]);
return true;
}
boolean isSingleConnect = options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_SUB || options.type == ZMQ.ZMQ_REQ;
if (isSingleConnect) {
if (endpoints.hasValues(addr)) {
// nonsensical results.
return true;
}
}
// Choose the I/O thread to run the session in.
IOThread ioThread = chooseIoThread(options.affinity);
if (ioThread == null) {
errno.set(ZError.EMTHREAD);
return false;
}
Address paddr = new Address(protocol, address);
// Resolve address (if needed by the protocol)
protocol.resolve(paddr, options.ipv6);
// Create session.
SessionBase session = Sockets.createSession(ioThread, true, this, options, paddr);
assert (session != null);
// PGM does not support subscription forwarding; ask for all data to be
// sent to this pipe. (same for NORM, currently?)
boolean subscribe2all = protocol.subscribe2all;
Pipe newpipe = null;
if (options.immediate || subscribe2all) {
// Create a bi-directional pipe.
ZObject[] parents = { this, session };
boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
int[] hwms = { conflate ? -1 : options.sendHwm, conflate ? -1 : options.recvHwm };
boolean[] conflates = { conflate, conflate };
Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
// Attach local end of the pipe to the socket object.
attachPipe(pipes[0], subscribe2all, true);
newpipe = pipes[0];
// Attach remote end of the pipe to the session object later on.
session.attachPipe(pipes[1]);
}
// Save last endpoint URI
options.lastEndpoint = paddr.toString();
addEndpoint(addr, session, newpipe);
return true;
}
use of zmq.io.net.NetProtocol in project jeromq by zeromq.
the class SocketBase method termEndpoint.
public final boolean termEndpoint(String addr) {
lock();
try {
// Check whether the library haven't been shut down yet.
if (ctxTerminated) {
errno.set(ZError.ETERM);
return false;
}
// Check whether endpoint address passed to the function is valid.
if (addr == null) {
errno.set(ZError.EINVAL);
return false;
}
// Process pending commands, if any, since there could be pending unprocessed processOwn()'s
// (from launchChild() for example) we're asked to terminate now.
boolean rc = processCommands(0, false, null);
if (!rc) {
return false;
}
SimpleURI uri = SimpleURI.create(addr);
NetProtocol protocol = checkProtocol(uri.getProtocol());
if (protocol == null) {
return false;
}
// Disconnect an inproc socket
if (protocol == NetProtocol.inproc) {
if (unregisterEndpoint(addr, this)) {
return true;
}
Collection<Pipe> olds = inprocs.remove(addr);
if (olds == null || olds.isEmpty()) {
errno.set(ZError.ENOENT);
return false;
} else {
for (Pipe old : olds) {
old.sendDisconnectMsg();
old.terminate(true);
}
}
return true;
}
String resolvedAddress = addr;
// socket is connected or bound, try with both.
if (protocol == NetProtocol.tcp) {
boolean endpoint = endpoints.hasValues(resolvedAddress);
if (!endpoint) {
// TODO V4 resolve TCP address when unbinding
IZAddress address = protocol.zresolve(uri.getAddress(), options.ipv6);
resolvedAddress = address.address().toString();
endpoint = endpoints.hasValues(resolvedAddress);
if (!endpoint) {
// no luck, try with local resolution
InetSocketAddress socketAddress = address.resolve(uri.getAddress(), options.ipv6, true);
resolvedAddress = socketAddress.toString();
}
}
}
// Find the endpoints range (if any) corresponding to the addr_ string.
Collection<EndpointPipe> eps = endpoints.remove(resolvedAddress);
if (eps == null || eps.isEmpty()) {
errno.set(ZError.ENOENT);
return false;
} else {
// If we have an associated pipe, terminate it.
for (EndpointPipe ep : eps) {
if (ep.pipe != null) {
ep.pipe.terminate(false);
}
termChild(ep.endpoint);
}
}
return true;
} finally {
unlock();
}
}
use of zmq.io.net.NetProtocol in project jeromq by zeromq.
the class SessionBase method startConnecting.
private void startConnecting(boolean wait) {
assert (active);
// Choose I/O thread to run connecter in. Given that we are already
// running in an I/O thread, there must be at least one available.
IOThread ioThread = chooseIoThread(options.affinity);
assert (ioThread != null);
// Create the connecter object.
NetProtocol protocol = addr.protocol();
if (protocol == null) {
errno.set(ZError.EPROTONOSUPPORT);
return;
}
switch(protocol) {
case tcp:
if (options.socksProxyAddress != null) {
Address proxyAddress = new Address(NetProtocol.tcp, options.socksProxyAddress);
SocksConnecter connecter = new SocksConnecter(ioThread, this, options, addr, proxyAddress, wait);
launchChild(connecter);
} else {
TcpConnecter connecter = new TcpConnecter(ioThread, this, options, addr, wait);
launchChild(connecter);
}
break;
case ipc:
{
IpcConnecter connecter = new IpcConnecter(ioThread, this, options, addr, wait);
launchChild(connecter);
}
break;
case tipc:
{
TipcConnecter connecter = new TipcConnecter(ioThread, this, options, addr, wait);
launchChild(connecter);
}
break;
case pgm:
case epgm:
{
assert (options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_XPUB || options.type == ZMQ.ZMQ_SUB || options.type == ZMQ.ZMQ_XSUB);
// For EPGM transport with UDP encapsulation of PGM is used.
boolean udpEncapsulation = protocol == NetProtocol.epgm;
// exists with PGM anyway.
if (options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_XPUB) {
// PGM sender.
PgmSender pgmSender = new PgmSender(ioThread, options);
boolean rc = pgmSender.init(udpEncapsulation, addr);
assert (rc);
sendAttach(this, pgmSender);
} else {
// PGM receiver.
PgmReceiver pgmReceiver = new PgmReceiver(ioThread, options);
boolean rc = pgmReceiver.init(udpEncapsulation, addr);
assert (rc);
sendAttach(this, pgmReceiver);
}
}
break;
case norm:
{
// exists with NORM anyway.
if (options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_XPUB) {
// NORM sender.
NormEngine normSender = new NormEngine(ioThread, options);
boolean rc = normSender.init(addr, true, false);
assert (rc);
sendAttach(this, normSender);
} else {
// NORM receiver.
NormEngine normReceiver = new NormEngine(ioThread, options);
boolean rc = normReceiver.init(addr, false, true);
assert (rc);
sendAttach(this, normReceiver);
}
}
break;
default:
assert (false);
break;
}
}
Aggregations