对 Actor 的后续调用会冻结程序

发布于 2024-11-05 07:27:23 字数 2598 浏览 0 评论 0原文

我将下面的代码放在一起;目的是让一个非阻塞服务器接受连接,然后将此连接传递给参与者进行进一步处理。第一次可以正常工作,但在后续请求时,程序冻结在 conServ 处! servSoc.accept。有什么想法为什么会发生这种情况吗?

import java.net._
import java.io._

import java.nio._
import java.nio.channels._

import java.util._

import scala.actors.Actor
import scala.actors.Actor._

def test() = {  
    var channel: ServerSocketChannel = null
    val isa: InetSocketAddress = new InetSocketAddress(23)

    val conServ = actor { 
        react {
            case conn: Socket => {                              
                                try {
                                    var pw: PrintWriter = new PrintWriter(conn.getOutputStream(), true)
                                    pw.println("Current time: " + new Date)
                                    pw.close
                                    conn.close
                                } catch {
                                    case ioe: IOException => println("IOException: " + ioe.getMessage)
                                    case e: Exception => println("Exception: " + e.getMessage)
                                }                               
                            }
        }
    }

    try {
        channel = ServerSocketChannel.open
        channel.configureBlocking(false)
        channel.socket().bind(isa)
        var selector: Selector = Selector.open
        channel.register(selector, SelectionKey.OP_ACCEPT)
        println("** Server ready for requests **")

        while (true) {
            if (selector.select > 0) {
                var selKeys: Set[SelectionKey] = selector.selectedKeys
                var selIt: Iterator[SelectionKey] = selKeys.iterator
                while (selIt.hasNext) {
                    var key: SelectionKey = selIt.next.asInstanceOf[SelectionKey]
                    selIt.remove
                    if (key.isAcceptable) {
                        var ssc: ServerSocketChannel = key.channel.asInstanceOf[ServerSocketChannel]
                        var servSoc: ServerSocket = ssc.socket
                        try {
                            conServ ! servSoc.accept
                        } catch {
                            case ioe: IOException => println(ioe.printStackTrace)
                        }
                    }
                }
            } else {
                continue
            }
        }

    } catch {
        case ioe: IOException => println("Could not listen to port 23. " + ioe.printStackTrace)
        case e: Exception => println("Error: " + e.printStackTrace)
    }
}

test

I put together the code below; the intent was to have a non-blocking server accept a connection and then pass off this connection to an actor for further processing. This works the first time through, but on the subsequent request the program freezes at conServ ! servSoc.accept. Any ideas why this is happening?

import java.net._
import java.io._

import java.nio._
import java.nio.channels._

import java.util._

import scala.actors.Actor
import scala.actors.Actor._

def test() = {  
    var channel: ServerSocketChannel = null
    val isa: InetSocketAddress = new InetSocketAddress(23)

    val conServ = actor { 
        react {
            case conn: Socket => {                              
                                try {
                                    var pw: PrintWriter = new PrintWriter(conn.getOutputStream(), true)
                                    pw.println("Current time: " + new Date)
                                    pw.close
                                    conn.close
                                } catch {
                                    case ioe: IOException => println("IOException: " + ioe.getMessage)
                                    case e: Exception => println("Exception: " + e.getMessage)
                                }                               
                            }
        }
    }

    try {
        channel = ServerSocketChannel.open
        channel.configureBlocking(false)
        channel.socket().bind(isa)
        var selector: Selector = Selector.open
        channel.register(selector, SelectionKey.OP_ACCEPT)
        println("** Server ready for requests **")

        while (true) {
            if (selector.select > 0) {
                var selKeys: Set[SelectionKey] = selector.selectedKeys
                var selIt: Iterator[SelectionKey] = selKeys.iterator
                while (selIt.hasNext) {
                    var key: SelectionKey = selIt.next.asInstanceOf[SelectionKey]
                    selIt.remove
                    if (key.isAcceptable) {
                        var ssc: ServerSocketChannel = key.channel.asInstanceOf[ServerSocketChannel]
                        var servSoc: ServerSocket = ssc.socket
                        try {
                            conServ ! servSoc.accept
                        } catch {
                            case ioe: IOException => println(ioe.printStackTrace)
                        }
                    }
                }
            } else {
                continue
            }
        }

    } catch {
        case ioe: IOException => println("Could not listen to port 23. " + ioe.printStackTrace)
        case e: Exception => println("Error: " + e.printStackTrace)
    }
}

test

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

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

发布评论

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

评论(2

暖阳 2024-11-12 07:27:23

将您的 react 包含在 loop 块中,如下所示:

val conServ = actor { 
  loop {
    react {
      // ...
    }
  }
}

现在发生的情况是,您的 Actor 已启动,处理第一条消息,并且不再“反应”以处理其他消息从它的队列中。

请参阅使用循环的 actor 的 act 方法

Enclose your react in a loop block like this:

val conServ = actor { 
  loop {
    react {
      // ...
    }
  }
}

What happens now, is that your actor is started, processes the first message and is not "reacting" again to process additional message from its queue.

See An actor's act method that uses loop.

夜司空 2024-11-12 07:27:23

这就是演员所做的,一次处理一条消息。您想要的是一个单独的线程来处理每个请求。为此,您可以尝试使用 Futures。

This is what an actor do, treating one message at the time. What you want is a separate thread to handle each request. For this you can try using Futures.

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