Package org.deftserver.web

Source Code of org.deftserver.web.HttpServer

package org.deftserver.web;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.util.List;

import org.deftserver.io.IOLoop;
import org.deftserver.util.Closeables;
import org.deftserver.web.http.HttpProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

public class HttpServer {
 
  private final Logger logger = LoggerFactory.getLogger(HttpServer.class);
 
  private static final int MIN_PORT_NUMBER = 1;
  private static final int MAX_PORT_NUMBER = 65535;
 
  private ServerSocketChannel serverChannel;
  private final List<IOLoop> ioLoops = Lists.newLinkedList();
 
  private final Application application;
 
  public HttpServer(Application application) {
    this.application = application;
  }

  /**
   * If you want to run Deft on multiple threads first invoke {@link #bind(int)} then {@link #start(int)}
   * instead of {@link #listen(int)} (listen starts Deft http server on a single thread with the default IOLoop
   * instance: {@code IOLoop.INSTANCE}).
   *
   * @return this for chaining purposes
   */
  public void listen(int port) {
    bind(port);
    ioLoops.add(IOLoop.INSTANCE);
    registerHandler(IOLoop.INSTANCE, new HttpProtocol(application));
  }
 
  public void bind(int port) {
    if (port <= MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
      throw new IllegalArgumentException("Invalid port number. Valid range: [" +
          MIN_PORT_NUMBER + ", " + MAX_PORT_NUMBER + ")");
    }
   
    try {
      serverChannel = ServerSocketChannel.open();
      serverChannel.configureBlocking(false);
    } catch (IOException e) {
      logger.error("Error creating ServerSocketChannel: {}", e);
    }
   
    InetSocketAddress endpoint = new InetSocketAddress(port)// use "any" address
    try {
      serverChannel.socket().bind(endpoint);
    } catch (IOException e) {
      logger.error("Could not bind socket: {}", e);
   
  }
 
  public void start(int numThreads) {
    for (int i = 0; i < numThreads; i++) {
      final IOLoop ioLoop = new IOLoop();
      ioLoops.add(ioLoop);
      final HttpProtocol protocol = new HttpProtocol(ioLoop, application);
      new Thread(new Runnable() {
       
        @Override public void run() {
          registerHandler(ioLoop, protocol);
          ioLoop.start();
        }
      }).start();
    }
  }
 
  /**
   * Unbinds the port and shutdown the HTTP server
   */
  public void stop() {
    logger.debug("Stopping HTTP server");
    for (IOLoop ioLoop : ioLoops) {
      // TODO RS 110527 Should probably do this in each IOLoop through an AsyncCallback
      // (hint: ioloop.addCallback(..))
      Closeables.closeQuietly(ioLoop, serverChannel);
    }
  }
 
  private void registerHandler(IOLoop ioLoop, HttpProtocol protocol) {
    ioLoop.addHandler(
        serverChannel,
        protocol,
        SelectionKey.OP_ACCEPT,
        null /*attachment*/
    );
  }

TOP

Related Classes of org.deftserver.web.HttpServer

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.