Problem with Actors and Networking
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
.
精彩评论