Pergunta

Eu tenho um servidor web cultivado em casa em meu aplicativo. Este servidor web gera um novo segmento para cada solicitação que vem no soquete para ser aceito. Eu quero que o servidor web que esperar até um ponto específico é atingido no segmento em que acabou de criar.

Já passei por muitos posts sobre este site e exemplos na web, mas não pode ter o servidor web para prosseguir depois de eu dizer o segmento para esperar. Um exemplo de código básico seria ótimo.

É a palavra-chave sincronizada a maneira correta de fazer isso? Se sim, como isso pode ser alcançado? exemplos de código estão abaixo do meu aplicativo:

Web Server

while (true) {
  //block here until a connection request is made
  socket = server_socket.accept();

  try {
    //create a new HTTPRequest object for every file request
    HttpRequest request = new HttpRequest(socket, this);

    //create a new thread for each request
    Thread thread = new Thread(request);

    //run the thread and have it return after complete
    thread.run();

    ///////////////////////////////
    wait here until notifed to proceed
    ///////////////////////////////
  } catch (Exception e) {
    e.printStackTrace(logFile);
  }
}

Código de rosca

public void run() {
  //code here

  //notify web server to continue here
}

Update - código final é como abaixo. O HttpRequest não apenas chamar resumeListener.resume() sempre que eu enviar um cabeçalho de resposta (é claro que também adicionando a interface como uma classe separada eo método addResumeListener(ResumeListener r1) em HttpRequest):

parte Web Server

// server infinite loop
while (true) {

  //block here until a connection request is made
  socket = server_socket.accept();

  try {
    final Object locker = new Object();

    //create a new HTTPRequest object for every file request
    HttpRequest request = new HttpRequest(socket, this);

    request.addResumeListener(new ResumeListener() {
      public void resume() {
        //get control of the lock and release the server
        synchronized(locker) {
          locker.notify();
        }
      }
    });

    synchronized(locker) {
      //create a new thread for each request
      Thread thread = new Thread(request);

      //run the thread and have it return after complete
      thread.start();

      //tell this thread to wait until HttpRequest releases
      //the server
      locker.wait();
    }
  } catch (Exception e) {
    e.printStackTrace(Session.logFile);
  }
}
Foi útil?

Solução

Primeiro de tudo, eu ecoar o sentimento dos outros que re-inventar a roda aqui provavelmente levará a uma variedade de questões para você. No entanto, se você quiser ir por este de qualquer maneira estrada que você está tentando fazer não é difícil. Você já experimentou com Jetty?

Talvez algo como isto:

public class MyWebServer {

  public void foo() throws IOException {
    while (true) {
      //block here until a connection request is made
      ServerSocket socket = new ServerSocket();

      try {
        final Object locker = new Object();
        //create a new HTTPRequest object for every file request
        MyRequest request = new MyRequest(socket);
        request.addResumeListener(new ResumeListener() {
          public void resume() {
            locker.notify();
          }
        });
        synchronized(locker){

          //create a new thread for each request
          Thread thread = new Thread(request);

          //start() the thread - not run()
          thread.start();

          //this thread will block until the MyRequest run method calls resume
          locker.wait();
        }  
      } catch (Exception e) {
      }

    }
  }
}

public interface ResumeListener {
  public void resume();
}

public class MyRequest implements Runnable{
  private ResumeListener resumeListener;

  public MyRequest(ServerSocket socket) {
  }

  public void run() {
    // do something
    resumeListener.resume(); //notify server to continue accepting next request
  }

  public void addResumeListener(ResumeListener rl) {
    this.resumeListener = rl;
  }
}

Outras dicas

Você pode usar java.util.concurrent .CountDownLatch com uma contagem de 1 para isso. Organizar para uma instância que seja criado e compartilhado pelo segmento pai e criança (por exemplo, criar-lo no construtor do HttpRequest, e tê-lo recuperáveis ??por uma função de membro). O servidor seguida, chama await() sobre ele, e os hits de rosca countDown() quando estiver pronto para liberar seu pai.

Você provavelmente precisará usar um Java Condição . De docs:

Condições (também conhecidos como condição filas ou variáveis ??de condição) fornecer um meio para um segmento para suspender execução (a "espera") até ser notificado por outro segmento que algum estado condição pode agora ser verdade.

Executar sob um depurador e definir um ponto de interrupção?

Se inviável, em seguida, ler uma linha de System.in?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top