Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple servers in a single EventMachine reactor

Is it possible to run multiple servers within a single event machine?

What I mean is that multiple services can be used concurrently by a single client connection. For example, a login server authenticates a user and then a user can use both a chat room and a simple game such as checkers with a single client socket concurrently?

Or do I need multiple eventmachine reactors for each service?

like image 266
david Avatar asked May 27 '11 22:05

david


1 Answers

I tried this and it's working:

#!/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
}

Here you get 3 echo services with different ports. (I was too lazy to implement different services.)

So, it's very easy to build a huge multi service wrapper.


Update

Simple code example for condition based start of a EM server:

#!/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!"
  }
}

In this example the echo server on port 8083 is started ~10 secs after app start. Try to telnet localhost 8083 before and after this timer, you'll see the effect.

You also can use values lower than 1 sec like 0.01 for every 1/100th sec checks.

This might be your starting point for your own ideas. The periodic timer is your internal loop, where you hook in your conditional checks for starting further services.


Good tutorial (PDF): eventmachine introduction (blog post)

like image 183
asaaki Avatar answered Sep 26 '22 23:09

asaaki