5 votes

Comment puis-je définir un délai d'attente pour un appel bloqué ?

J'ai un serveur de chat multi-threads qui fonctionne avec plusieurs clients (chaque client est traité dans un nouveau thread).

Si un client se déconnecte, le thread correspondant sur le serveur s'accroche à inputstream.readLine() qui est un appel bloquant.

Comment puis-je définir une sorte de délai d'attente afin de pouvoir fermer le socket et libérer le thread après 2000 ms sans réponse ?

class Handler(socket: Socket) extends Runnable {
  def run() : Unit = {
    val inputstream = new BufferedReader(new InputStreamReader(socket.getInputStream()))
    val outputstream = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
    var break = false
    while(break != true){
      val input = inputstream.readLine() // blocking call
// how do i time out after 2000ms?
      input match {
        case "update" =>
          outputstream.write("message")
          outputstream.newLine()
          outputstream.flush()
        case _ => // any other input, break and close socket
          break = true
      }
    }
    socket.close()
  }
}

object ChatServer extends App {
  val server = new ServerSocket(10000)
  while(true) {
    val socket = server.accept // blocking call
    (new Thread(new Handler(socket))).start()
    // some condition{
    //   server.close()
    // }
  }
}

5voto

Yuval Itzchakov Points 13820

Vous pouvez utiliser [BufferedReader.ready()](https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#ready()) :

Vrai si le prochain read() est garanti de ne pas bloquer pour l'entrée, faux. sinon. Notez que retourner false ne garantit pas que la prochaine lecture sera bloquée.

class Handler(socket: Socket) extends Runnable {
  def run(): Unit = {
    val inputstream = new BufferedReader(new InputStreamReader(socket.getInputStream))
    val outputstream = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream))

    var break = false
    val startTime = System.currentTimeMillis()

    while (!break) {
      if (inputstream.ready()) {
        val input = inputstream.readLine()
        input match {
          case "update" =>
            outputstream.write("message")
            outputstream.newLine()
            outputstream.flush()
          case _ => // any other input, break and close socket
            break = true
        }
      } else if (System.currentTimeMillis() - startTime >= 2000) {
        break = true
      }
    }
    socket.close()
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X