All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.gwtrpcplus.server.internal.RpcManagerServer Maven / Gradle / Ivy

The newest version!
package com.googlecode.gwtrpcplus.server.internal;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.google.gwt.event.shared.HandlerRegistration;
import com.googlecode.gwtrpcplus.server.internal.RpcPlusClient.RpcPlusClientHandler;
import com.googlecode.gwtrpcplus.server.internal.type.RequestMethodHandler;
import com.googlecode.gwtrpcplus.server.internal.type.RequestMethodHandler.RequestMethodAnswerer;
import com.googlecode.gwtrpcplus.server.internal.type.RequestMethodHandlerBasic;
import com.googlecode.gwtrpcplus.server.internal.type.RequestMethodHandlerQueued;
import com.googlecode.gwtrpcplus.server.internal.type.RequestMethodHandlerServerpush;
import com.googlecode.gwtrpcplus.server.internal.util.HttpServletRequestMinimum;
import com.googlecode.gwtrpcplus.server.internal.util.Logger;

public class RpcManagerServer {
  private Logger logger = new Logger(RpcManagerServer.class);

  private final HashMap requestMethodHandlers;

  private final ConcurrentHashMap clients = new ConcurrentHashMap();

  private final Runnable obsoleteRemover = new Runnable() {
    @Override
    public void run() {
      Iterator> it = clients.entrySet().iterator();
      while (it.hasNext()) {
        Entry e = it.next();
        if (e.getValue().isObsolete()) {
          logger.info("Client timed out: id={}", e.getKey());
          e.getValue().disconnect();
          it.remove();
        }
      }
      logger.trace("Connected Clients: {}", clients.size());
    }
  };

  private final Runnable keepAliveSender = new Runnable() {
    @Override
    public void run() {
      Iterator> it = clients.entrySet().iterator();
      while (it.hasNext()) {
        Entry e = it.next();
        logger.trace("calling clients keepalive: id={}", e.getKey());
        e.getValue().keepAlive();
      }
      logger.trace("Connected Clients: {}", clients.size());
    }
  };

  public RpcManagerServer(RequestMethodHandlerBasic basic, RequestMethodHandlerServerpush push,
      RequestMethodHandlerQueued queued, ScheduledExecutorService executor) {
    // TODO make configurable
    this.requestMethodHandlers = new HashMap<>();
    this.requestMethodHandlers.put(basic.getRequestTypeName(), basic);
    this.requestMethodHandlers.put(push.getRequestTypeName(), push);
    this.requestMethodHandlers.put(queued.getRequestTypeName(), queued);
    executor.scheduleAtFixedRate(obsoleteRemover, 0, 30, TimeUnit.SECONDS);
    executor.scheduleAtFixedRate(keepAliveSender, 0, RpcPlusClient.KEEPALIVE_TIMEOUT / 2, TimeUnit.MILLISECONDS);
  }

  public void onCall(final String clientId, String data, String contextPath, String permStrongName,
      String reqModuleBasePath, HttpSession httpSession) {
    if (contextPath == null)
      logger.warn("No ContextPath given");

    onCall(clientId, data, new HttpServletRequestMinimum(contextPath, permStrongName, reqModuleBasePath, httpSession));
  }

  public void onCall(final String clientId, String data, HttpServletRequest req) {
    logger.trace("Call from Client {}", data.substring(0, Math.min(data.length(), 150)));

    if (data.equals("disconnect")) {
      RpcPlusClient client = clients.remove(clientId);
      if (client != null) {
        client.disconnect();
        logger.info("Client timed out: id={}", clientId);
      }
      return;
    }

    get(clientId).touch();

    final String requestId = data.substring(0, data.indexOf("#"));
    data = data.substring(data.indexOf("#") + 1);
    final String type = data.substring(0, data.indexOf("#"));
    data = data.substring(data.indexOf("#") + 1);
    final String service = data.substring(0, data.indexOf("#"));
    data = data.substring(data.indexOf("#") + 1);

    RequestMethodHandler h = requestMethodHandlers.get(type);
    if (h == null)
      throw new IllegalArgumentException("Type \"" + type + "\" isn't registered");
    h.process(service, data, req, new RequestMethodAnswerer() {
      @Override
      public void send(String answer) {
        String response = requestId + "#" + answer;
        answer(clientId, response);
      }
    });
  }

  private RpcPlusClient get(String clientId) {
    RpcPlusClient client = clients.get(clientId);
    if (client == null) {
      client = new RpcPlusClient();
      RpcPlusClient old = clients.putIfAbsent(clientId, client);
      if (old != null)
        return old;
      logger.info("Client added: id={}", clientId);
    }
    return client;
  }

  private void answer(final String clientId, String response) {
    get(clientId).addResponse(response);
  }

  public HandlerRegistration addHandler(final String clientId, final RpcPlusClientHandler handler) {
    return get(clientId).addHandler(handler);
  }

  public String getResponse(String clientId) {
    return get(clientId).getResponse();
  }

  public String getResponseAndWait(String clientId) {
    return get(clientId).getResponseAndWait();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy