2
我們需要用Scala RemotActors創建一個可以處理多個客戶端的服務器。例如聊天服務器,它將每個收到的消息回覆給所有連接的客戶端。我們目前的嘗試是爲每個客戶端創建一個可以收聽並回復所有收到的消息的actor。但是演員的動態註冊不起作用。Scala服務器需要管理很多客戶端
import actors.{Actor, OutputChannel}
import actors.remote.{RemoteActor, Node, FreshNameCreator}
object Server extends Actor{
class ConnectedClient(id:Symbol,out:OutputChannel[Any]) extends Actor{
start
def act {
loop {
react {
case m:ServerMessage =>
out ! m
case m:ClientMessage =>
Server ! m
}
}
}
}
RemoteActor.alive(9999)
RemoteActor.register('server, this) //'
println("Server started.")
var clients = new collection.mutable.HashSet[ConnectedClient]
def act {
loop {
react {
case 'connect => //'
println("Server: New Client")
val id = FreshNameCreator.newName
val client = new ConnectedClient(id,sender)
clients += client
RemoteActor.register(id, client) // This seems not to work
reply(id)
case ClientMessage(m) =>
println("Server: received: " + m)
for(client <- clients)
client ! ServerMessage(m)
case m =>
println("Server: Unknown Message: " + m)
}
}
}
}
case class ServerMessage(m:String)
case class ClientMessage(m:String)
class Client(serverNode:Node) extends Actor{
println("Client: connecting...")
val server = RemoteActor.select(serverNode, 'server) //'
start
def act{
//we want the symbol that is intended to identify our personal Actor at the Server
val id = (server !? 'connect).asInstanceOf[Symbol] //'
val personalServer = RemoteActor.select(serverNode, id)
println("Client["+id+"]: connected")
loop{
react{
case ServerMessage(m) =>
println("Client["+id+"]: " + m)
case m:String =>
personalServer ! ClientMessage(m)
case m =>
println("Server: Unknown Message: " + m)
}
}
}
}
object Main{
def main(args:Array[String]){
Server.start
val serverNode = Node("localhost",9999)
val clientA = new Client(serverNode)
val clientB = new Client(serverNode)
val clientC = new Client(serverNode)
clientA ! "Hello. I am A."
clientB ! "Hello. I am B."
clientC ! "Hello. I am C."
}
}
是的我已經發現,我自己,任何想法,爲什麼我必須這樣做? – Arne 2011-04-18 13:27:56