单个EventMachine反应器中的多个服务器

8

在单个事件机器中运行多个服务器是否可能?

我的意思是,一个单独的客户端连接可以同时使用多个服务。例如,登录服务器验证用户,然后用户可以同时使用聊天室和简单的游戏(如跳棋)与单个客户端套接字并发?

还是说我需要为每个服务使用多个eventmachine反应器?


如果协议是明确无歧的,我期望你应该能够在一个服务器进程中运行成千上万个不同的服务。 - sarnold
1个回答

7
我试过这个方法,它有效:

#!/usr/bin/env ruby

require 'eventmachine'

module EchoServer
  def post_init
    puts "-- someone connected to the echo server!"
  end
  def receive_data data
    send_data ">>>you sent: #{data}"
    close_connection if data =~ /quit/i
  end
  def unbind
    puts "-- someone disconnected from the echo server!"
  end
end

EventMachine::run {
  EventMachine::start_server "127.0.0.1", 8081, EchoServer
  EventMachine::start_server "127.0.0.1", 8082, EchoServer
  EventMachine::start_server "127.0.0.1", 8083, EchoServer
}

这里提供了三个使用不同端口的echo服务(我太懒了,没有实现不同的服务)。

因此,构建一个大型多服务包装器非常容易。


更新

条件启动EM服务器的简单代码示例:

#!/usr/bin/env ruby
# encoding: utf-8

require 'eventmachine'

module EchoServer
  def post_init
    puts "-- someone connected to the echo server!"
  end
  def receive_data data
    send_data ">>>you sent: #{data}"
    close_connection if data =~ /quit/i
  end
  def unbind
    puts "-- someone disconnected from the echo server!"
  end
end

$check_ok = false

EventMachine::run {
  puts "checker var is: #{$check_ok}"
  EventMachine::start_server "127.0.0.1", 8081, EchoServer
  EventMachine::start_server "127.0.0.1", 8082, EchoServer
  puts "echos on 8081 and 8082 started."

  # periodic timer check - every 1 sec
  EventMachine.add_periodic_timer(1) {
    if $check_ok
      EventMachine::start_server "127.0.0.1", 8083, EchoServer
      $check_ok = false
      puts "echo on 8083 started!"
    end
  }
  # timer triggered after 10 secs - only once!
  EventMachine.add_timer(10) {
    $check_ok = true
    puts "checker var is #{$check_ok} now!"
  }
}

在本例中,在应用程序启动后约10秒钟启动8083端口上的回显服务器。在此计时器之前和之后尝试telnet localhost 8083,您将看到效果。
您还可以使用低于1秒的值,例如0.01,以进行每1/100秒的检查。
这可能是您自己想法的起点。定期计时器是您的内部循环,在其中挂钩您的条件检查以启动进一步的服务。
好的教程(PDF):eventmachine introduction博客文章

谢谢,那么对我来说这意味着如果需要的话无法在运行时添加更多的服务器。这正确吗? - david
不会说这是不可能的。您可以实现一个循环,在其中让服务在运行时添加 - 但这需要更深入地研究eventmachine。在这种情况下有用的是 EM.add_periodic_timer,以每x秒检查是否满足某个条件并且必须启动新的EM服务器,但尚未测试。 - asaaki
看一下更新后的答案,你会对服务运行时的启动有一个初步的了解。 - asaaki
谢谢你的帮助。我会再试试,但我认为IO::Reactor可能更适合我。 - david

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接