开发者

Problem with Actors and Networking

开发者 https://www.devze.com 2023-03-24 14:13 出处:网络
I have a weird problem with a ChatServer program I am working on (don\'t know why I suddenly started it but I want to finish it). First, here is the relevant code:

I have a weird problem with a ChatServer program I am working on (don't know why I suddenly started it but I want to finish it). First, here is the relevant code:

sealed trait ServerMessage

case class Message(msg: String) extends ServerMessage

case object Quit extends ServerMessage

sealed trait ClientMessage

case class Incoming(conn: Connection, msg: String) extends ClientMessage

case class Remove(conn: Connection) extends ClientMessage

object Server extends App with Actor with Settings {
  Console.println(greeting)
  Console.println("Server starting up...")

  val socket = new ServerSocket(defaultPort);
  var connections: Set[Connection] = Set.empty

  start

  actor {
    loop {
      val s = socket.accept
      val c = Connection(s)
      Console.println("New Connection from " + s.getInetAddress)
      c ! Message(greeting)
      connections += c
    }
  }

  def act = loop {
    receive {
      // For some reason, this only works once
      case Incoming(conn, msg) => {
        Console.println(conn.socket.getInetAddress.toString + " said: " + msg)
        connections.foreach(_ ! Message(msg))
      }
      case Remove(conn) => connections -= conn; conn ! Quit
    }
  }
}

case class Connection(socket: Socket) extends Actor {
  val in = new BufferedReader(new InputStreamReader(socket.getInputStream))
  val out = new PrintWriter(socket.getOutputStream)

  start

  actor {
    var s: String = in.readLine
    while (s != null) {
      // This output works
      scala.Console.println(s)
      if (s == "quit") Server ! Remove(this)
      else Server ! Incoming(this, s)
      s = in.readLine
    }
  }

  def act = {
    var done = false
    while (!done) {
      receive {
        // This seems to work all the time (I can send several messages)
        case Message(str) => out.println(str); out.flush
        case Quit => done = true
      }
    }
    in.close
    out.close
    socket.close
  }
}

The problem I have is when I connect to it via telnet, I can send 1 message, and it comes back to me. But after that, when I send more messages, they don't come back to me. With the help of the debug messages开发者_开发问答 I can identify where the problem is, but I can't see at all why it doesn't work.

Maybe someone can give me a hint? This is the first time I use actors in such a complex way.

EDIT: Could it have to do with the fact that the receive or react functions will never return?


Try replacing receive with react.

0

精彩评论

暂无评论...
验证码 换一张
取 消