2011-02-13 2 views
2

여러 클라이언트를 처리 할 수있는 Scala RemotActors로 서버를 만들어야합니다. 예를 들어 모든 수신 메시지를 모든 연결된 클라이언트에 회신하는 채팅 서버. 현재 우리는 수신 된 모든 메시지를 수신하고 응답 할 수있는 클라이언트 당 하나의 액터를 생성하려고합니다. 그러나 배우들의 역동적 인 등록은 효과가 없습니다.스칼라 서버가 많은 클라이언트를 관리해야합니다.

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

당신은 act 방법 내부 aliveregister를 호출해야합니다.

+0

예 나는 이미 그것을 알아 냈습니다. 어떤 생각을해야합니까? – Arne

+0

그냥 자연스러운 추측이지만 각 스레드는 액터 역할을하기 때문에 메인 스레드에서 호출하면 메인 액터가 원하는 액터가 아닌 외부에 등록됩니다. 그래도 시도해야 할 것입니다. – ron

관련 문제