Package tkuri.jxy.server

Source Code of tkuri.jxy.server.ClientPeer

/**
* (c) 2011-2012 tkuri
*/
package tkuri.jxy.server;

import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;

import tkuri.jxy.Const;
import tkuri.jxy.Util;
import tkuri.jxy.arch.ASelectionAttachment;
import tkuri.jxy.arch.ChannelReader;
import tkuri.jxy.arch.TheSelector;


/**
* ClientPeer
*/
public class ClientPeer extends ASelectionAttachment {

  static int ID = 0;

  private int id_ = ID++;

  private SelectionKey selKey_ = null;
  SocketChannel socket = null;
  ChannelReader reader = null;
  ClientRequest request = null;

  private ITransfer ascent_ = null;
  private LinkedList<ITransfer> descentQ_ = new LinkedList<ITransfer>();
  private ITransfer descent_ = null;


  /**
   * ctor
   *
   * @param aSock
   */
  public ClientPeer(SocketChannel aSock) throws Exception {

    socket = aSock;
    reader = new ChannelReader(aSock);

    socket.configureBlocking(false);

    selKey_ = TheSelector.registerChannel(
        socket,
        SelectionKey.OP_READ,
        this);
  }


  @Override
  public int interestOps() {

    if (selKey_.isValid()) {
      return selKey_.interestOps();
    } else {
      return 0;
    }
  }


  @Override
  public void interestOps(int aOps) {

    if (selKey_.isValid()) {
      selKey_.interestOps(aOps);
    }
  }


  @Override
  public void onSelected(Selector aSelector) {
  }


  @Override
  public void onAccept() {
  }


  @Override
  public void onConnect() {
  }


  @Override
  public boolean readFirst() {

    return true;
  }


  @Override
  public void onReadable() {

    reader.fill();

    _dispatchRequest();
  }


  //
  // リクエストを読む
  // ヘッダ未取得であれば,ヘッダを読む
  // 接続が切られれば invalidate
  // ヘッダ読み込み完了すれば ITransfer を生成
  // ITransfer があれば処理を委譲
  //
  private void _dispatchRequest() {

    if (ascent_ == null) {
      if (request == null) {
        request = new ClientRequest(reader);
        //Util.say("client", id_, ": new clientRequest");
      }

      if (request.queryState() < ClientRequest.STS_HEADER) {
        if (reader.available() < 0) {
          Util.say("client", id_, ": wait for clientRequest... client reader.avail < 0");
          wantToRead(false);
          termIfIdle();
        }
        return;
      }

      ascent_ = OriginDispatcher.dispatch(this, request.host, request.port);
    }

    ascent_.onClientReadable(); // no work :)
  }


  public void notifyRequestEnd() throws Exception {

    if (ascent_ == null) {
      Util.say("client", id_, ": asc==null but req end ???");
      return;
    }

    descentQ_.add(ascent_);

    // 次のリクエストを待つ
    request = null;
    ascent_ = null;
    _dispatchRequest();
  }


  public void notifyResponseStart() {

    // レスポンスを待つ
    //Util.say("client", id_, ": response will come. want to write");
    _takeNextResponse();
  }


  @Override
  public void onWritable() {

    descent_.onClientWritable();
  }


  private void _takeNextResponse() {

    if (descent_ == null) {
      descent_ = descentQ_.pollFirst();
      if (descent_ == null) {
        Util.say("client", id_, ": no next descent");
        termIfIdle();
        return;
      }
      //Util.say("client", id_, ": GOT next descent: " + descent);
      wantToWrite(true);
    }
  }


  public void notifyResponseEnd() {

    Util.say("client", id_, ": notifyResEnd");

    descent_ = null;
    wantToWrite(false);
    _takeNextResponse();
  }


  public void termIfIdle() {

    if (ascent_ == null && descent_ == null && descentQ_.size() == 0) {
      invalidate();
    }
  }


  public void invalidate() {

    Util.say("client", id_, ": invalidate()");
    Util.close(socket);
    selKey_.cancel();
  }


  public boolean isValid() {

    return selKey_.isValid();
  }


  @Override
  public String toString() {

    return "ClientPeer" + id_ + ": asc = " + ascent_ + " / dsc = " + descent_;
  }
}
TOP

Related Classes of tkuri.jxy.server.ClientPeer

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.