Scala 服务器需要管理许多客户端

发布于 2024-10-17 12:09:24 字数 2758 浏览 4 评论 0原文

我们需要使用 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."
    }
}

We need to create a Server with Scala RemotActors, that can handle multiple clients. Eg a chat server that replies every received message back to all connected clients. Our current attempt is to create one actor per client that can listen and reply to all received messages. But the the dynamic registration of the actors does not work.

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."
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没有心的人 2024-10-24 12:09:24

您必须在 act 方法内调用 aliveregister

You have to call alive and register inside the act method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文