Search in sources :

Example 1 with SessionBase

use of zmq.io.SessionBase 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;
}
Also used : Address(zmq.io.net.Address) IZAddress(zmq.io.net.Address.IZAddress) InetSocketAddress(java.net.InetSocketAddress) Pipe(zmq.pipe.Pipe) SessionBase(zmq.io.SessionBase) IOThread(zmq.io.IOThread) NetProtocol(zmq.io.net.NetProtocol)

Example 2 with SessionBase

use of zmq.io.SessionBase in project jeromq by zeromq.

the class TcpListener method acceptEvent.

@Override
public void acceptEvent() {
    SocketChannel channel;
    try {
        channel = accept();
        // If connection was reset by the peer in the meantime, just ignore it.
        if (channel == null) {
            socket.eventAcceptFailed(endpoint, ZError.EADDRNOTAVAIL);
            return;
        }
        TcpUtils.tuneTcpSocket(channel);
        TcpUtils.tuneTcpKeepalives(channel, options.tcpKeepAlive, options.tcpKeepAliveCnt, options.tcpKeepAliveIdle, options.tcpKeepAliveIntvl);
    } catch (IOException e) {
        // If connection was reset by the peer in the meantime, just ignore it.
        // TODO: Handle specific errors like ENFILE/EMFILE etc.
        socket.eventAcceptFailed(endpoint, ZError.exccode(e));
        return;
    }
    // remember our fd for ZMQ_SRCFD in messages
    // socket.setFd(channel);
    // Create the engine object for this connection.
    StreamEngine engine = null;
    try {
        engine = new StreamEngine(channel, options, endpoint);
    } catch (ZError.InstantiationException e) {
        socket.eventAcceptFailed(endpoint, ZError.EINVAL);
        return;
    }
    // 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 and launch a session object.
    SessionBase session = Sockets.createSession(ioThread, false, socket, options, null);
    assert (session != null);
    session.incSeqnum();
    launchChild(session);
    sendAttach(session, engine, false);
    socket.eventAccepted(endpoint, channel);
}
Also used : ServerSocketChannel(java.nio.channels.ServerSocketChannel) SocketChannel(java.nio.channels.SocketChannel) StreamEngine(zmq.io.StreamEngine) ZError(zmq.ZError) IOThread(zmq.io.IOThread) IOException(java.io.IOException) SessionBase(zmq.io.SessionBase)

Aggregations

IOThread (zmq.io.IOThread)2 SessionBase (zmq.io.SessionBase)2 IOException (java.io.IOException)1 InetSocketAddress (java.net.InetSocketAddress)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 ZError (zmq.ZError)1 StreamEngine (zmq.io.StreamEngine)1 Address (zmq.io.net.Address)1 IZAddress (zmq.io.net.Address.IZAddress)1 NetProtocol (zmq.io.net.NetProtocol)1 Pipe (zmq.pipe.Pipe)1