bayeuxservlet.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 327 行

JAVA
327
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Emil Ong */package com.caucho.bayeux;import java.io.*;import java.util.*;import java.util.concurrent.*;import java.util.logging.Level;import java.util.logging.Logger;import javax.servlet.*;import javax.servlet.http.*;import com.caucho.util.*;import com.caucho.vfs.*;import com.caucho.servlet.comet.*;/** * Servlet to handle bayeux requests. */public class BayeuxServlet extends GenericCometServlet {  private static final Logger log =     Logger.getLogger(BayeuxServlet.class.getName());  private static final L10N L = new L10N(BayeuxServlet.class);  private static final ChannelTree _root = new ChannelTree();  private static final ConcurrentHashMap<String,BayeuxClient> _clients =     new ConcurrentHashMap<String,BayeuxClient>();  /**   * Services the initial request.   *   * @param request the servlet request object   * @param response the servlet response object   * @param controller the controller to be passed to application code   *   * @return true for keepalive, false for the end of the request   */  @Override  public boolean service(ServletRequest req,                         ServletResponse resp,                         CometController controller)    throws IOException, ServletException  {    HttpServletRequest request = (HttpServletRequest) req;    HttpServletResponse response = (HttpServletResponse) resp;    if (! "POST".equals(request.getMethod())) {      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);      return false;    }    try {      String message = request.getParameter("message");      if (log.isLoggable(Level.FINEST)) {        log.finest("message = " + message);      }      JsonObject object = JsonDecoder.decode(message);      if (! (object instanceof JsonArray)) {        response.sendError(HttpServletResponse.SC_BAD_REQUEST);        // XXX: Allow single JsonMap object        return false;      }      JsonArray array = (JsonArray) object;      for (int i = 0; i < array.size(); i++) {        if (! (array.get(i) instanceof JsonMap))          continue;        JsonMap map = (JsonMap) array.get(i);        JsonObject channelObject = map.get("channel");        if (! (channelObject instanceof JsonString))          continue;        String channel = channelObject.toString();        if ("/meta/handshake".equals(channel)) {          handleHandshake(map, request, response, controller);          // the handshake is handled as normal HTTP request, so disconnect          return false;        }        else if ("/meta/connect".equals(channel)) {          return handleConnect(map, request, response, controller);        }        else if ("/meta/subscribe".equals(channel)) {          return handleSubscribe(map, request, response, controller);        }      }      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown channel");      return false;    }    catch (JsonDecodingException e) {      throw new ServletException(e);    }  }  /**   * Resumes service the initial request.   *   * @param request the servlet request object   * @param response the servlet response object   * @param controller the controller to be passed to application code   *   * @return true for keepalive, false for the end of the request   */  @Override  public boolean resume(ServletRequest request,                        ServletResponse response,                        CometController controller)    throws IOException, ServletException  {    return false;  }  private void handleHandshake(JsonMap map,                               HttpServletRequest request,                               HttpServletResponse response,                               CometController controller)    throws IOException, ServletException  {    PrintWriter out = response.getWriter();    JsonObject version = map.get("version");    JsonObject supportedConnectionTypes = map.get("supportedConnectionTypes");    JsonObject minimumVersion = map.get("minimumVersion");    JsonObject ext = map.get("ext");    JsonObject id = map.get("id");    if (version == null) {      sendHandshakeResponse(out, null, id, false, "missing version");      return;    }    if (supportedConnectionTypes == null) {      sendHandshakeResponse(out, null, id, false,                             "missing supportedConnectionTypes");      return;    }    UUID uuid = UUID.randomUUID();    sendHandshakeResponse(out, uuid.toString(), id, true, null);  }  private void sendHandshakeResponse(PrintWriter out,                                      String clientId,                                      JsonObject id,                                      boolean success,                                     String error)    throws IOException, ServletException  {    out.println("[");    out.println("\t{");    out.println("\t\t\"channel\": \"/meta/handshake\",");    out.println("\t\t\"version\": \"1.0beta\",");    out.println("\t\t\"supportedConnectionTypes\": " +                 "[\"long-polling\", \"callback-polling\", \"iframe\"],");    if (clientId != null)       out.println("\t\t\"clientId\": \"" + clientId + "\",");    out.println("\t\t\"successful\": \"" + success + "\",");    if (id != null && (id instanceof JsonString))      out.println("\t\t\"id\": \"" + id + "\",");    if (error != null)      out.println("\t\t\"error\": \"" + error + "\",");    out.println("\t}");    out.println("]");  }  private boolean handleConnect(JsonMap map,                                HttpServletRequest request,                                HttpServletResponse response,                                CometController controller)    throws IOException, ServletException  {    PrintWriter out = response.getWriter();    JsonObject clientId = map.get("clientId");    JsonObject connectionType = map.get("connectionType");    JsonObject ext = map.get("ext");    JsonObject id = map.get("id");    BayeuxClient client = _clients.get(clientId);    /* XXX    if (client != null)      clientId = UUID.randomUUID().toString();*/    for (BayeuxConnectionType type : BayeuxConnectionType.values()) {      if (type.toString().equals(connectionType)) {        client = new BayeuxClient(controller, clientId.toString(), type);        _clients.put(clientId.toString(), client);        sendConnectResponse(out, clientId, id, true, null);        return true;      }    }    sendConnectResponse(out, clientId, id, false, "bad connection type");    return false;  }  private void sendConnectResponse(PrintWriter out,                                    JsonObject clientId,                                    JsonObject id,                                    boolean success,                                   String error)    throws IOException, ServletException  {    out.println("[");    out.println("\t{");    out.println("\t\t\"channel\": \"/meta/connect\",");    if (clientId != null)       out.println("\t\t\"clientId\": \"" + clientId + "\",");    out.println("\t\t\"successful\": \"" + success + "\",");    if (id != null)      out.println("\t\t\"id\": \"" + id + "\",");    if (error != null)      out.println("\t\t\"error\": \"" + error + "\",");    out.println("\t}");    out.println("]");  }  private boolean handleSubscribe(JsonMap map,                                  HttpServletRequest request,                                  HttpServletResponse response,                                  CometController controller)    throws IOException, ServletException  {    PrintWriter out = response.getWriter();    JsonObject clientId = map.get("clientId");    JsonObject subscription = map.get("subscription");    JsonObject id = map.get("id");    JsonObject ext = map.get("ext");    BayeuxClient client = _clients.get(clientId);    if (client == null) {      sendSubcribeResponse(out, clientId, subscription, id, false,                            "Unknown client");      return false;    }    _root.subscribe(subscription.toString(), client);    sendSubcribeResponse(out, clientId, subscription, id, true, null);    return false;  }  private void sendSubcribeResponse(PrintWriter out,                                     JsonObject clientId,                                     JsonObject subscription,                                     JsonObject id,                                     boolean success,                                    String error)    throws IOException, ServletException  {    out.println("[");    out.println("\t{");    out.println("\t\t\"channel\": \"/meta/subscribe\",");    if (clientId != null)       out.println("\t\t\"clientId\": \"" + clientId + "\",");    if (subscription != null)       out.println("\t\t\"subscription\": \"" + subscription + "\",");    out.println("\t\t\"successful\": \"" + success + "\",");    if (id != null)      out.println("\t\t\"id\": \"" + id + "\",");    if (error != null)      out.println("\t\t\"error\": \"" + error + "\",");    out.println("\t}");    out.println("]");  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?