Package org.cometd.server

Examples of org.cometd.server.Transport


    /* ------------------------------------------------------------ */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // Look for an existing client and protect from context restarts
        Object clientObj = request.getAttribute(CLIENT_ATTR);
        Transport transport = null;
        int received = -1;
        boolean metaConnectDeliveryOnly = false;
        boolean pendingResponse = false;
        boolean metaConnect = false;
        final boolean initial;

        // Have we seen this request before
        AtmosphereBayeuxClient client = (clientObj instanceof ClientImpl) ? (AtmosphereBayeuxClient) clientObj : null;
        if (client != null) {
            initial = false;
            // yes - extract saved properties
            transport = (Transport) request.getAttribute(TRANSPORT_ATTR);
            transport.setResponse(response);
            metaConnectDeliveryOnly = client.isMetaConnectDeliveryOnly() || transport.isMetaConnectDeliveryOnly();
            metaConnect = true;
        } else {
            initial = true;
            Message[] messages = getMessages(request);
            received = messages.length;

            /* check jsonp parameter */
            String jsonpParam = request.getParameter("jsonp");

            // Handle all received messages
            try {
                for (Message message : messages) {
                    if (jsonpParam != null)
                        message.put("jsonp", jsonpParam);

                    if (client == null) {
                        String clientId = (String) message.get(AbstractBayeux.CLIENT_FIELD);
                        client = (AtmosphereBayeuxClient) _bayeux.getClient(clientId);

                        // If no client, SHOULD be a handshake, so force a
                        // transport and handle
                        if (client == null) {
                            // Setup a browser ID
                            String browser_id = findBrowserId(request);
                            if (browser_id == null)
                                browser_id = setBrowserId(request, response);

                            if (transport == null) {
                                transport = _bayeux.newTransport(client, message);
                                transport.setResponse(response);
                                metaConnectDeliveryOnly = transport.isMetaConnectDeliveryOnly();
                            }
                            _bayeux.handle(null, transport, message);
                            message = null;
                            continue;
                        }
                    }

                    String browser_id = findBrowserId(request);
                    if (browser_id != null && (client.getBrowserId() == null || !client.getBrowserId().equals(browser_id)))
                        client.setBrowserId(browser_id);

                    // resolve transport
                    if (transport == null) {
                        transport = _bayeux.newTransport(client, message);
                        transport.setResponse(response);
                        metaConnectDeliveryOnly = client.isMetaConnectDeliveryOnly() || transport.isMetaConnectDeliveryOnly();
                    }

                    // Tell client to hold messages as a response is likely to
                    // be sent.
                    if (!metaConnectDeliveryOnly && !pendingResponse) {
                        pendingResponse = true;
                        client.responsePending();
                    }

                    if (Bayeux.META_CONNECT.equals(message.getChannel()))
                        metaConnect = true;

                    _bayeux.handle(client, transport, message);
                }
            }
            finally {
                for (Message message : messages)
                    ((MessageImpl) message).decRef();
                if (pendingResponse) {
                    client.responded();
                }
            }
        }

        Message metaConnectReply = null;

        // Do we need to wait for messages
        if (transport != null) {
            metaConnectReply = transport.getMetaConnectReply();
            if (metaConnectReply != null) {
                long timeout = client.getTimeout();
                if (timeout == 0)
                    timeout = _bayeux.getTimeout();

                //Continuation continuation=ContinuationSupport.getContinuation(request);
                AtmosphereResource<HttpServletRequest, HttpServletResponse> continuation
                        = (AtmosphereResource) request.getAttribute(
                        AtmosphereServlet.ATMOSPHERE_RESOURCE);

                // Get messages or wait
                synchronized (client) {
                    if (!client.hasNonLazyMessages() && initial && received <= 1) {
                        // save state and suspend
                        request.setAttribute(CLIENT_ATTR, client);
                        request.setAttribute(TRANSPORT_ATTR, transport);
                        continuation.suspend(timeout, false);
                        client.setContinuation(continuation);
                        return;
                    }
                }

                client.setContinuation(null);
                transport.setMetaConnectReply(null);
            } else if (client != null) {
                client.access();
            }
        }

        if (client != null) {
            if (metaConnectDeliveryOnly && !metaConnect) {
                // wake up any long poll
                client.resume();
            } else {
                List<Message> messages;
                synchronized (client) {
                    client.doDeliverListeners();

                    ArrayQueue<Message> clientMessages = (ArrayQueue<Message>) client.getQueue();
                    // Copy the messages to avoid synchronization
                    messages = new ArrayList<Message>(clientMessages);
                    // Empty client's queue
                    clientMessages.clear();
                }

                final int size = messages.size();
                for (int i = 0; i < size; i++) {
                    final Message message = messages.get(i);
                    final MessageImpl mesgImpl = (message instanceof MessageImpl) ? (MessageImpl) message : null;

                    // Can we short cut the message?
                    if (i == 0 && size == 1 && mesgImpl != null && _refsThreshold > 0 && metaConnectReply != null && transport instanceof JSONTransport) {
                        // is there a response already prepared
                        ByteBuffer buffer = mesgImpl.getBuffer();
                        if (buffer != null) {
                            // Send pre-prepared buffer
                            request.setAttribute("org.mortbay.jetty.ResponseBuffer", buffer);
                            if (metaConnectReply instanceof MessageImpl)
                                ((MessageImpl) metaConnectReply).decRef();
                            metaConnectReply = null;
                            transport = null;
                            mesgImpl.decRef();
                            continue;
                        } else if (mesgImpl.getRefs() >= _refsThreshold) {
                            // create multi-use buffer
                            byte[] contentBytes = ("[" + mesgImpl.getJSON() + ",{\"" + Bayeux.SUCCESSFUL_FIELD + "\":true,\"" + Bayeux.CHANNEL_FIELD
                                    + "\":\"" + Bayeux.META_CONNECT + "\"}]").getBytes(StringUtil.__UTF8);
                            int contentLength = contentBytes.length;

                            String headerString = "HTTP/1.1 200 OK\r\n" + "Content-Type: text/json; charset=utf-8\r\n" + "Content-Length: "
                                    + contentLength + "\r\n" + "\r\n";

                            byte[] headerBytes = headerString.getBytes(StringUtil.__UTF8);

                            buffer = ByteBuffer.allocateDirect(headerBytes.length + contentLength);
                            buffer.put(headerBytes);
                            buffer.put(contentBytes);
                            buffer.flip();

                            mesgImpl.setBuffer(buffer);
                            request.setAttribute("org.mortbay.jetty.ResponseBuffer", buffer);
                            metaConnectReply = null;
                            if (metaConnectReply instanceof MessageImpl)
                                ((MessageImpl) metaConnectReply).decRef();
                            transport = null;
                            mesgImpl.decRef();
                            continue;
                        }
                    }

                    if (message != null)
                        transport.send(message);
                    if (mesgImpl != null)
                        mesgImpl.decRef();
                }

                if (metaConnectReply != null) {
                    metaConnectReply = _bayeux.extendSendMeta(client, metaConnectReply);
                    transport.send(metaConnectReply);
                    if (metaConnectReply instanceof MessageImpl)
                        ((MessageImpl) metaConnectReply).decRef();
                }
            }
        }

        if (transport != null)
            transport.complete();
    }
View Full Code Here

TOP

Related Classes of org.cometd.server.Transport

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.