Package org.jboss.errai.bus.server.servlet

Source Code of org.jboss.errai.bus.server.servlet.GrizzlyCometServlet

package org.jboss.errai.bus.server.servlet;

import com.google.inject.Singleton;

import com.sun.grizzly.comet.CometContext;
import com.sun.grizzly.comet.CometEngine;
import com.sun.grizzly.comet.CometEvent;
import com.sun.grizzly.comet.handlers.ReflectorCometHandler;
import org.jboss.errai.bus.client.framework.MarshalledMessage;
import org.jboss.errai.bus.server.MessageQueue;
import org.jboss.errai.bus.server.QueueActivationCallback;
import org.jboss.errai.bus.server.QueueSession;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.*;

/**
* The <tt>GrizzlyCometServlet</tt> provides the HTTP-protocol gateway between the server bus and the client buses,
* using Glassfish.
*/
@Singleton
public class GrizzlyCometServlet extends AbstractErraiServlet implements Serializable {

    private static final long serialVersionUID = -2919167206889576861L;

    private CometContext context = null;
    private final Map<MessageQueue, QueueSession> queueToSession = new HashMap<MessageQueue, QueueSession>();
    private final Map<QueueSession, Set<HttpServletResponse>> activeEvents = new HashMap<QueueSession, Set<HttpServletResponse>>();
    private ReflectorCometHandler handler = null;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);   
    }

    private CometContext createCometContext(String id) {
        CometEngine cometEngine = CometEngine.getEngine();
        CometContext ctx = cometEngine.register(id);
        ctx.setExpirationDelay(-1);
        return ctx;
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String sessionId = request.getSession().getId();
        final QueueSession session = sessionProvider.getSession(request.getSession());
        PrintWriter attach = response.getWriter();

        if (context == null) {

            context = createCometContext(sessionId);

            handler = new ReflectorCometHandler(true, buildStartingMessage(response), "");

            handler.attach(attach);
            context.addCometHandler(handler);
        } else {

            boolean post = "POST".equals(request.getMethod());

            MessageQueue queue = getQueue(session, !post);

            if (queue != null) {
                synchronized (activeEvents) {
                    Set<HttpServletResponse> responses = activeEvents.get(session);

                    if (!post && queue.messagesWaiting()) {
                        context.notify(getMessages(response, queue), CometEvent.NOTIFY, handler);
                    }

                    if (!queueToSession.containsKey(queue))
                        queueToSession.put(queue, session);

                    if (responses == null)
                        activeEvents.put(session, responses = new HashSet<HttpServletResponse>());

                    if (!responses.contains(response))
                        responses.add(response);
                }
            } else {
                // FIXME!!!!!!!!!!!!!!!
                // SEND ERROR
            }
        }
    }

    private String getMessages(final HttpServletResponse httpServletResponse, MessageQueue queue) throws IOException {
        httpServletResponse.setHeader("Cache-Control", "no-cache");
        //    httpServletResponse.addHeader("Payload-Size", String.valueOf(messages.size()));
        httpServletResponse.setContentType("application/json");
        StringBuilder sb = new StringBuilder();

        List<MarshalledMessage> messages = queue.poll(false).getMessages();
        Iterator<MarshalledMessage> iter = messages.iterator();

        sb.append('[');
        while (iter.hasNext()) {
            writeToOutputStream(sb, iter.next());
            if (iter.hasNext()) {
                sb.append(',');
            }
        }
        sb.append(']');

        queue.heartBeat();

        return sb.toString();
    }


    /**
     * Before suspending message
     *
     * @return
     */
    private String buildStartingMessage(HttpServletResponse response) throws IOException {
        response.setHeader("Cache-Control", "no-cache");
        response.addHeader("Payload-Size", "1");
        response.setContentType("application/json");

        StringBuilder sb = new StringBuilder();

        sb.append('[');

        writeToOutputStream(sb, new MarshalledMessage() {
            public String getSubject() {
                return "ClientBusErrors";
            }

            public Object getMessage() {
                StringBuilder b = new StringBuilder("{ErrorMessage:\"").append(CONFIG_PROBLEM_TEXT).append("\",AdditionalDetails:\"");
                return b.append("\"}").toString();
            }
        });

        sb.append(',');

        writeToOutputStream(sb, new MarshalledMessage() {
            public String getSubject() {
                return "ClientBus";
            }

            public Object getMessage() {
                return "{CommandType:\"Disconnect\"}";
            }
        });


        sb.append(']');

        return sb.toString();
    }

    /**
     * Writes the message to the output stream
     *
     * @param sb - the string builder to write to
     * @param m  - the message to write to the stream
     * @throws java.io.IOException - is thrown if any input/output errors occur while writing to the stream
     */
    private void writeToOutputStream(StringBuilder sb, MarshalledMessage m) throws IOException {
        sb.append('{');
        sb.append('"');
        for (byte b : (m.getSubject()).getBytes()) {
            sb.append(b);
        }
        sb.append('"');
        sb.append(':');

        if (m.getMessage() == null) {
            sb.append('n');
            sb.append('u');
            sb.append('l');
            sb.append('l');
        } else {
            for (byte b : ((String) m.getMessage()).getBytes()) {
                sb.append(b);
            }
        }
        sb.append('}');
    }

    private MessageQueue getQueue(QueueSession session, boolean pause) {

        System.out.println("getQueue !!!!!! " + service  + " " +  service.getBus() + " " +
                session.getSessionId() + " " + service.getBus().getQueue(session.getSessionId()));

        MessageQueue queue = service.getBus().getQueue(session.getSessionId());

        System.out.println("getQueue !!!!!! " + pause + ":pause, queue is " + queue == null);
       
        if (pause && queue != null && queue.getActivationCallback() == null) {

            System.out.println("getQueue !!!!!! in first if");

            queue.setActivationCallback(new QueueActivationCallback() {
                volatile boolean resumed = false;

                public void activate(MessageQueue queue) {
                    System.out.println("getQueue !!!!!! activate");

                    if (resumed) {
                        return;
                    }
                    resumed = true;
                    queue.setActivationCallback(null);

                    try {

                        System.out.println("getQueue !!!!!! first try block");

                        Set<HttpServletResponse> activeSessEvents;
                        QueueSession session;
                        session = queueToSession.get(queue);
                        if (session == null) {
                            System.out.println("getQueue !!!!!! session is null");

                            queue.stopQueue();
                            return;
                        }

                        activeSessEvents = activeEvents.get(queueToSession.get(queue));

                        if (activeSessEvents == null || activeSessEvents.isEmpty()) {
                            return;
                        }

                        HttpServletResponse hsr = activeSessEvents.iterator().next();

                        if (hsr == null) {
                            return;
                        }

                        try {

                            System.out.println("getQueue !!!!!! second try block");
                            context.notify(getMessages(hsr, queue), CometEvent.NOTIFY, handler);
                        }
                        catch (NullPointerException e) {

                            System.out.println("getQueue !!!!!! NPE caught");

                            activeSessEvents.remove(hsr);
                            return;
                        }
                    }
                    catch (Exception e) {

                        System.out.println("getQueue !!!!!! exception caught" + e);

                        e.printStackTrace();
                    }
                }
            });
        }

        return queue;
    }

    private static final String CONFIG_PROBLEM_TEXT =
            "\n\n*************************************************************************************************\n"
                    + "** PROBLEM!\n"
                    + "** It appears something has been incorrectly configured. In order to use ErraiBus\n"
                    + "** on Glassfish, you must ensure that you are using the NIO or APR connector. Also \n"
                    + "** make sure that you have added these lines to your WEB-INF/web.xml file:\n"
                    + "**                                              ---\n"
                    + "**    <servlet>\n" +
                    "**        <servlet-name>GrizzlyErraiServlet</servlet-name>\n" +
                    "**        <servlet-class>org.jboss.errai.bus.server.servlet.GrizzlyCometServlet</servlet-class>\n" +
                    "**        <load-on-startup>1</load-on-startup>\n" +
                    "**    </servlet>\n" +
                    "**\n" +
                    "**    <servlet-mapping>\n" +
                    "**        <servlet-name>GrizzlyErraiServlet</servlet-name>\n" +
                    "**        <url-pattern>*.erraiBus</url-pattern>\n" +
                    "**    </servlet-mapping>\n"
                    + "**                                              ---\n"
                    + "** If you have the following lines in your WEB-INF/web.xml, you must comment or remove them:\n"
                    + "**                                              ---\n"
                    + "**    <listener>\n" +
                    "**        <listener-class>org.jboss.errai.bus.server.ErraiServletConfig</listener-class>\n" +
                    "**    </listener>\n"
                    + "*************************************************************************************************\n\n";
}
TOP

Related Classes of org.jboss.errai.bus.server.servlet.GrizzlyCometServlet

TOP
Copyright © 2018 www.massapi.com. 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.