2011-02-13 79 views
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." 
    } 
} 

回答

1

你必須調用aliveregisteract方法內。

+0

是的我已經發現,我自己,任何想法,爲什麼我必須這樣做? – Arne 2011-04-18 13:27:56