Package de.netseeker.ejoe

Examples of de.netseeker.ejoe.ConnectionHeader


    /**
     * @param client
     */
    public void returnEJClient( EJClient client )
    {
        ConnectionHeader header = client.getConnectionHeader();
        if ( header != null && header.isPersistent() )
        {
            synchronized ( _mutex )
            {
                ejClientInstances.put( new UID().toString(), client );
            }
View Full Code Here


                }

                Iterator it = _selector.selectedKeys().iterator();
                SelectionKey selKey = null;
                SocketChannel cChannel = null;
                ConnectionHeader header = null;

                while ( it.hasNext() && !isInterrupted() )
                {
                    selKey = (SelectionKey) it.next();
                    it.remove();

                    try
                    {
                        // validate the key
                        if ( !selKey.isValid() )
                        {
                            continue;
                        }

                        // socket is ready for establishing a connection?
                        if ( selKey.isAcceptable() )
                        {
                            // establish the connection
                            cChannel = this._channel.accept();

                            // a little bit paranoia
                            if ( cChannel != null )
                            {
                                // little bit tuning
                                cChannel.socket().setTrafficClass( EJConstants.IPTOS_THROUGHPUT );
                                cChannel.socket().setReuseAddress( true );
                                cChannel.socket().setSoLinger( false, 0 );
                               
                                // ensure that the socket channel is prepared
                                // for non-blocking operations
                                cChannel.configureBlocking( false );
                                // create a new ConnectionHeader for all
                                // upcoming operations on the
                                // accepted socket connection
                                header = new ConnectionHeader( cChannel, cChannel.socket().getRemoteSocketAddress()
                                        .toString(), true );
                                // register the channel on another thread which
                                // will do further connection handling
                                getProcessor().register( header, SelectionKey.OP_READ );
View Full Code Here

        try
        {
            Iterator it;
            SocketChannel cChannel;
            SelectionKey selKey;
            ConnectionHeader clientInfo;
            Set keys;

            while ( !isInterrupted() )
            {
                this._load = 0;

                // (pre)register interested socket channels
                registerAspirants();

                // just try endless new selects until there are interested
                // socket channels
                if ( _selector.select() == 0 ) continue;

                keys = this._selector.selectedKeys();
                this._load = keys.size();
                it = this._selector.selectedKeys().iterator();

                // loop over all selected channels, just take care of thread
                // interruption
                while ( it.hasNext() && !isInterrupted() )
                {
                    selKey = (SelectionKey) it.next();
                    // remove the SelectionKey from the Iterator otherwise it
                    // will be lost
                    it.remove();

                    try
                    {
                        // validate the key
                        if ( !selKey.isValid() ) continue;

                        // at least our ConnectionAcceptor has created a client
                        // ConnectionHeader
                        clientInfo = (ConnectionHeader) selKey.attachment();

                        // first check read-availbility
                        if ( selKey.isReadable() )
                        {
                            // get the underlying socket channel
                            cChannel = (SocketChannel) selKey.channel();
                            // cancel the channels registration with our
                            // Selector
                            selKey.cancel();

                            // little bit paranoia
                            if ( cChannel != null && cChannel.isOpen() )
                            {
                                // don't we support NIO?
                                if ( !this._serverInfo.hasNonBlockingReadWrite() )
                                {
                                    logger.log( Level.FINEST,
                                                "Setting socket to blocking mode for further io operations..." );

                                    // prepare the channel for upcoming blocking
                                    // network operations
                                    cChannel.configureBlocking( true );
                                }

                                // schedule a asynchronious read-process operation
                                this._readpool.invokeLater( new ConnectionReader( this, this._serverInfo, clientInfo ) );
                            }
                        }
                        else if ( selKey.isWritable() )
                        {
                            // get the underlying socket channel
                            cChannel = (SocketChannel) selKey.channel();
                            // cancel the channels registration with our
                            // Selector
                            selKey.cancel();

                            // little bit paranoia
                            if ( cChannel != null && cChannel.isOpen() )
                            {
                                // don't we support NIO?
                                if ( !this._serverInfo.hasNonBlockingReadWrite() )
                                {
                                    if ( !clientInfo.hasAttachment() ) continue;
                                    // prepare the channel for upcoming blocking
                                    // network operations
                                    cChannel.configureBlocking( true );
                                }
View Full Code Here

        if ( size > 0 )
        {
            // clean out cancelled key list
            this._selector.selectNow();
            Object[] arr = null;
            ConnectionHeader header = null;
            SocketChannel channel = null;
            SelectionKey sk = null;

            for ( ; count < size; count++ )
            {
                arr = (Object[]) this._aspirants.remove( 0 );
                header = (ConnectionHeader) arr[0];
                channel = header.getChannel();
                // set a previously blocking socket channel to non-blocking
                // mode to allow selector operations on it
                if ( channel.isBlocking() )
                {
                    logger.log( Level.FINEST,
View Full Code Here

     * @throws IOException
     */
    public ConnectionHeader handshake( final ConnectionHeader header, SocketChannel channel, long timeout )
            throws IOException, ParseException
    {
        ConnectionHeader receiverHeader;
        ByteBuffer magicBuf = null;

        try
        {
            // shall we act as clientside and initialize the handshake?
            if ( header.isClient() )
            {
                // ok, get the control bits as well as the adapter name in a
                // ByteChannel
                ByteBuffer tmpBuf = header.toByteBuffer();
                magicBuf = ByteBufferAllocator.allocate( tmpBuf.remaining() + 4, false );
                magicBuf.putInt( EJConstants.EJOE_MAGIC_NUMBER );
                magicBuf.put( tmpBuf );
                magicBuf.flip();
                logger.log( Level.FINEST, "Sending Clientheader: " + header );
                semiBlockingWrite( channel, magicBuf, timeout );
                if ( magicBuf.hasRemaining() ) return null;
                // the server will just answer with the header byte
                magicBuf.clear();
                magicBuf.limit( 1 );
            }
            else
            {
                // expect to read the header byte and an integer (the size of
                // the forthcoming adapter name string)
                // the magic integer was already read in #handshake
                magicBuf = ByteBufferAllocator.allocate( 5, false );
            }

            // Server: read the client header byte + sizeof adapter name
            // Client: read just the server header byte
            semiBlockingRead( channel, magicBuf, timeout );
            if ( magicBuf.hasRemaining() )
            {
                throw new ParseException( "Header too long!", magicBuf.position() );
            }

            magicBuf.flip();
            InetAddress address = channel.socket().getInetAddress();
            int port = channel.socket().getPort();
            receiverHeader = new ConnectionHeader( channel, address.getHostAddress() + ':' + port, header.isClient(),
                                                   magicBuf.get() );

            // shall we act as server side and answer to the handshake request?
            if ( !header.isClient() )
            {
                if ( receiverHeader.hasAdapter() )
                {
                    // ok, we have already read the client header byte, now read
                    // the adapter name string
                    if ( readAdapterName( receiverHeader, magicBuf, timeout ) == -1 ) return null;
                }

                // answer to the client request and send our serverside
                // headerbyte
                magicBuf.clear();
                magicBuf.limit( 1 );
                magicBuf.put( header.toByte() );
                magicBuf.flip();
                semiBlockingWrite( channel, magicBuf, timeout );
                if ( magicBuf.hasRemaining() ) return null;
            }

            receiverHeader.setConnected( true );
        }
        finally
        {
            ByteBufferAllocator.collect( magicBuf );
        }
View Full Code Here

     */
    public ConnectionHeader handshake( final ConnectionHeader header, SocketChannel channel, long timeout )
            throws IOException, ParseException
    {
        boolean isHttp = header.isHttp();
        ConnectionHeader receiverHeader = null;
        ByteBuffer magicBuf = null;
        byte[] preReadData = null;

        if ( !header.isClient() )
        {
            // expect to read the first four bytes for determining the used protocol
            magicBuf = ByteBufferAllocator.allocate( 4, false );
            semiBlockingRead( channel, magicBuf, timeout );
            // at least the handshake must be read in one operation
            // if not prevent us from dealing with bad networks or crappy clients
            if ( magicBuf.hasRemaining() ) return null;
            magicBuf.flip();
            // copy the read four byte into a buffer - we will need them again maybe
            preReadData = new byte[4];
            magicBuf.get( preReadData );
            magicBuf.rewind();
            // read the first four bytes as int
            int magicNo = magicBuf.getInt();
            isHttp = (magicNo != EJConstants.EJOE_MAGIC_NUMBER);
        }

        try
        {
            // seems like the usual EJOE protocol
            if ( !isHttp )
            {
                // complete the handshake using our DefaultChannel, we can skip the preread four bytes
                receiverHeader = DefaultChannel.getInstance().handshake( header, channel, timeout );
            }
            // seems like HTTP protocol
            else
            {
                // complete the handshake using a HttpChannel and hand over the preread four bytes
                receiverHeader = ((HttpChannel) HttpChannel.getInstance()).handshake( header, channel, preReadData,
                                                                                      timeout );
            }

            // copy the host into the received client header
            if ( receiverHeader.isClient() && receiverHeader.getHost() == null )
            {
                receiverHeader.setHost( header.getHost() );
            }
            // copy the adapter into the returned server header
            if ( header.isClient() && header.hasAdapter() && receiverHeader.getAdapterName() == null )
            {
                receiverHeader.setAdapterName( header.getAdapterName() );
            }
        }
        catch ( IncompleteIOException ioe )
        {
            // nothing to do
View Full Code Here

     * @throws ParseException
     */
    public ConnectionHeader handshake( final ConnectionHeader header, SocketChannel channel, byte[] prereadHead,
                                       long timeout ) throws IOException, ParseException
    {
        ConnectionHeader receiverHeader;
        String host = null;
        ByteBuffer magicBuf = null;
        ByteBuffer hBuffer = null;

        // shall we act as clientside and initialize the handshake?
        if ( header.isClient() )
        {
            // create a new HTTP HEAD operation and send our client header and the requested adapter (if any)
            hBuffer = new HttpRequest( header, HttpRequest.HTTP_HEAD ).toByteBuffer();
            semiBlockingWrite( channel, hBuffer, timeout );
            // something strange happened - at least the handshake data must be written in one operation
            if ( hBuffer.hasRemaining() ) return null;
        }

        // read and parse the HTTP header - this can also preread one or more bytes of none-header-data (content)
        HttpHeaderParser parser = readHttpHeader( channel, prereadHead, timeout, header.isClient() );

        // little bit paranoia
        if ( parser == null )
        {
            return null;
        }

        // get the read ByteBuffer
        magicBuf = parser.getByteHeader();

        if ( header.isClient() )
        {
            // did the HTTP parser already read the content? if so the ByteBuffer has already the required size.
            if ( magicBuf == null )
            {
                // allocate an appropiate ByteBuffer
                magicBuf = ByteBufferAllocator.allocate( parser.getContentLength() );
            }

            // did the HTTP parser already read the complete content (the eight bits of the header byte)?
            if ( magicBuf.position() < (parser.getContentLength() - 1) )
            {
                // read the data part
                semiBlockingRead( channel, magicBuf, timeout );
                if ( magicBuf.hasRemaining() ) return null;
            }

            magicBuf.flip();

            if ( logger.isLoggable( Level.FINEST ) )
            {
                logger.log( Level.FINEST, "HTTP-Header read: "
                        + IOUtil.bBitsToSBits( IOUtil.byteToBBits( magicBuf.get() ) ) );
                magicBuf.rewind();
            }

            receiverHeader = new ConnectionHeader( channel, host, header.isClient(), magicBuf.get() );
        }
        // shall we act as server side and answer to the handshake request?
        else
        {
            receiverHeader = new ConnectionHeader( channel, host, header.isClient() );
            // the HTTP header must contain the eight header bits in the requested URI
            receiverHeader.fromString( ((HttpRequestParser) parser).getUri() );

            // does the http header overwrite the compression setting?
            receiverHeader.setCompression( header.hasCompression() && parser.hasCompression() );

            // does the http header overwrite the setting for using a persistent connection?
            receiverHeader.setPersistent( parser.isPersistentConnection() && header.isPersistent() );

            // answer to the client request and send our serverside headerbyte
            // clients as browsers (IE, Firefox, Opera) or similiar doesn't understand our handshake
            // hence we send our handshake response only when the client tells us that it is able
            // to parse our response
            if ( receiverHeader.isHandshakeResponseAware() )
            {
                // create a HTTP response with just our server header byte as content
                HttpResponse response = new HttpResponse( header, HttpResponse.HTTP_OK );
                response.addData( header.toByte() );
                logger.log( Level.FINEST, "Sending server headerbyte: " + header );
                hBuffer = response.toByteBuffer();
                semiBlockingWrite( channel, hBuffer, timeout );
                if ( hBuffer.hasRemaining() ) return null;
            }
            // ok, a unknown client which might have already send some content with it's first request
            else if ( parser.hasPrereadContent() )
            {
                receiverHeader.setWaitingBuffer( parser.getByteHeader() );
            }
        }

        receiverHeader.setHttp( true );
        receiverHeader.setConnected( true );

        return receiverHeader;
    }
View Full Code Here

TOP

Related Classes of de.netseeker.ejoe.ConnectionHeader

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.