This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class EchoServer < EM::Connection
|
||||
def receive_data(data)
|
||||
send_data(data)
|
||||
end
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, EchoServer)
|
||||
end
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class EchoServer < EM::Connection
|
||||
def receive_data(data)
|
||||
if data.strip =~ /exit$/i
|
||||
EventMachine.stop
|
||||
else
|
||||
send_data(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, EchoServer)
|
||||
end
|
||||
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class SimpleChatServer < EM::Connection
|
||||
|
||||
@@connected_clients = Array.new
|
||||
DM_REGEXP = /^@([a-zA-Z0-9]+)\s*:?\s*(.+)/.freeze
|
||||
|
||||
attr_reader :username
|
||||
|
||||
|
||||
#
|
||||
# EventMachine handlers
|
||||
#
|
||||
|
||||
def post_init
|
||||
@username = nil
|
||||
|
||||
puts "A client has connected..."
|
||||
ask_username
|
||||
end
|
||||
|
||||
def unbind
|
||||
@@connected_clients.delete(self)
|
||||
puts "[info] #{@username} has left" if entered_username?
|
||||
end
|
||||
|
||||
def receive_data(data)
|
||||
if entered_username?
|
||||
handle_chat_message(data.strip)
|
||||
else
|
||||
handle_username(data.strip)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Username handling
|
||||
#
|
||||
|
||||
def entered_username?
|
||||
!@username.nil? && !@username.empty?
|
||||
end # entered_username?
|
||||
|
||||
def handle_username(input)
|
||||
if input.empty?
|
||||
send_line("Blank usernames are not allowed. Try again.")
|
||||
ask_username
|
||||
else
|
||||
@username = input
|
||||
@@connected_clients.push(self)
|
||||
self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
|
||||
puts "#{@username} has joined"
|
||||
|
||||
self.send_line("[info] Ohai, #{@username}")
|
||||
end
|
||||
end # handle_username(input)
|
||||
|
||||
def ask_username
|
||||
self.send_line("[info] Enter your username:")
|
||||
end # ask_username
|
||||
|
||||
|
||||
#
|
||||
# Message handling
|
||||
#
|
||||
|
||||
def handle_chat_message(msg)
|
||||
if command?(msg)
|
||||
self.handle_command(msg)
|
||||
else
|
||||
if direct_message?(msg)
|
||||
self.handle_direct_message(msg)
|
||||
else
|
||||
self.announce(msg, "#{@username}:")
|
||||
end
|
||||
end
|
||||
end # handle_chat_message(msg)
|
||||
|
||||
def direct_message?(input)
|
||||
input =~ DM_REGEXP
|
||||
end # direct_message?(input)
|
||||
|
||||
def handle_direct_message(input)
|
||||
username, message = parse_direct_message(input)
|
||||
|
||||
if connection = @@connected_clients.find { |c| c.username == username }
|
||||
puts "[dm] @#{@username} => @#{username}"
|
||||
connection.send_line("[dm] @#{@username}: #{message}")
|
||||
else
|
||||
send_line "@#{username} is not in the room. Here's who is: #{usernames.join(', ')}"
|
||||
end
|
||||
end # handle_direct_message(input)
|
||||
|
||||
def parse_direct_message(input)
|
||||
return [$1, $2] if input =~ DM_REGEXP
|
||||
end # parse_direct_message(input)
|
||||
|
||||
|
||||
#
|
||||
# Commands handling
|
||||
#
|
||||
|
||||
def command?(input)
|
||||
input =~ /(exit|status)$/i
|
||||
end # command?(input)
|
||||
|
||||
def handle_command(cmd)
|
||||
case cmd
|
||||
when /exit$/i then self.close_connection
|
||||
when /status$/i then self.send_line("[chat server] It's #{Time.now.strftime('%H:%M')} and there are #{self.number_of_connected_clients} people in the room")
|
||||
end
|
||||
end # handle_command(cmd)
|
||||
|
||||
|
||||
#
|
||||
# Helpers
|
||||
#
|
||||
|
||||
def announce(msg = nil, prefix = "[chat server]")
|
||||
@@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty?
|
||||
end # announce(msg)
|
||||
|
||||
def number_of_connected_clients
|
||||
@@connected_clients.size
|
||||
end # number_of_connected_clients
|
||||
|
||||
def other_peers
|
||||
@@connected_clients.reject { |c| self == c }
|
||||
end # other_peers
|
||||
|
||||
def send_line(line)
|
||||
self.send_data("#{line}\n")
|
||||
end # send_line(line)
|
||||
|
||||
def usernames
|
||||
@@connected_clients.map { |c| c.username }
|
||||
end # usernames
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
|
||||
end
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class SimpleChatServer < EM::Connection
|
||||
|
||||
#
|
||||
# EventMachine handlers
|
||||
#
|
||||
|
||||
def post_init
|
||||
puts "A client has connected..."
|
||||
end
|
||||
|
||||
def unbind
|
||||
puts "A client has left..."
|
||||
end
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
|
||||
end
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class SimpleChatServer < EM::Connection
|
||||
|
||||
@@connected_clients = Array.new
|
||||
|
||||
|
||||
#
|
||||
# EventMachine handlers
|
||||
#
|
||||
|
||||
def post_init
|
||||
@@connected_clients.push(self)
|
||||
puts "A client has connected..."
|
||||
end
|
||||
|
||||
def unbind
|
||||
@@connected_clients.delete(self)
|
||||
puts "A client has left..."
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Helpers
|
||||
#
|
||||
|
||||
def other_peers
|
||||
@@connected_clients.reject { |c| self == c }
|
||||
end # other_peers
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
|
||||
end
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class SimpleChatServer < EM::Connection
|
||||
|
||||
@@connected_clients = Array.new
|
||||
|
||||
|
||||
attr_reader :username
|
||||
|
||||
|
||||
#
|
||||
# EventMachine handlers
|
||||
#
|
||||
|
||||
def post_init
|
||||
@username = nil
|
||||
|
||||
puts "A client has connected..."
|
||||
ask_username
|
||||
end
|
||||
|
||||
def unbind
|
||||
@@connected_clients.delete(self)
|
||||
puts "A client has left..."
|
||||
end
|
||||
|
||||
def receive_data(data)
|
||||
if entered_username?
|
||||
handle_chat_message(data.strip)
|
||||
else
|
||||
handle_username(data.strip)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Username handling
|
||||
#
|
||||
|
||||
def entered_username?
|
||||
!@username.nil? && !@username.empty?
|
||||
end # entered_username?
|
||||
|
||||
def handle_username(input)
|
||||
if input.empty?
|
||||
send_line("Blank usernames are not allowed. Try again.")
|
||||
ask_username
|
||||
else
|
||||
@username = input
|
||||
@@connected_clients.push(self)
|
||||
self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
|
||||
puts "#{@username} has joined"
|
||||
|
||||
self.send_line("[info] Ohai, #{@username}")
|
||||
end
|
||||
end # handle_username(input)
|
||||
|
||||
def ask_username
|
||||
self.send_line("[info] Enter your username:")
|
||||
end # ask_username
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Message handling
|
||||
#
|
||||
|
||||
def handle_chat_message(msg)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Helpers
|
||||
#
|
||||
|
||||
def other_peers
|
||||
@@connected_clients.reject { |c| self == c }
|
||||
end # other_peers
|
||||
|
||||
def send_line(line)
|
||||
self.send_data("#{line}\n")
|
||||
end # send_line(line)
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
|
||||
end
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class SimpleChatServer < EM::Connection
|
||||
|
||||
@@connected_clients = Array.new
|
||||
|
||||
|
||||
attr_reader :username
|
||||
|
||||
|
||||
#
|
||||
# EventMachine handlers
|
||||
#
|
||||
|
||||
def post_init
|
||||
@username = nil
|
||||
|
||||
puts "A client has connected..."
|
||||
ask_username
|
||||
end
|
||||
|
||||
def unbind
|
||||
@@connected_clients.delete(self)
|
||||
puts "[info] #{@username} has left" if entered_username?
|
||||
end
|
||||
|
||||
def receive_data(data)
|
||||
if entered_username?
|
||||
handle_chat_message(data.strip)
|
||||
else
|
||||
handle_username(data.strip)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Username handling
|
||||
#
|
||||
|
||||
def entered_username?
|
||||
!@username.nil? && !@username.empty?
|
||||
end # entered_username?
|
||||
|
||||
def handle_username(input)
|
||||
if input.empty?
|
||||
send_line("Blank usernames are not allowed. Try again.")
|
||||
ask_username
|
||||
else
|
||||
@username = input
|
||||
@@connected_clients.push(self)
|
||||
self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
|
||||
puts "#{@username} has joined"
|
||||
|
||||
self.send_line("[info] Ohai, #{@username}")
|
||||
end
|
||||
end # handle_username(input)
|
||||
|
||||
def ask_username
|
||||
self.send_line("[info] Enter your username:")
|
||||
end # ask_username
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Message handling
|
||||
#
|
||||
|
||||
def handle_chat_message(msg)
|
||||
if command?(msg)
|
||||
self.handle_command(msg)
|
||||
else
|
||||
self.announce(msg, "#{@username}:")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Commands handling
|
||||
#
|
||||
|
||||
def command?(input)
|
||||
input =~ /exit$/i
|
||||
end # command?(input)
|
||||
|
||||
def handle_command(cmd)
|
||||
case cmd
|
||||
when /exit$/i then self.close_connection
|
||||
end
|
||||
end # handle_command(cmd)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Helpers
|
||||
#
|
||||
|
||||
def announce(msg = nil, prefix = "[chat server]")
|
||||
@@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty?
|
||||
end # announce(msg)
|
||||
|
||||
def other_peers
|
||||
@@connected_clients.reject { |c| self == c }
|
||||
end # other_peers
|
||||
|
||||
def send_line(line)
|
||||
self.send_data("#{line}\n")
|
||||
end # send_line(line)
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
|
||||
end
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems' # or use Bundler.setup
|
||||
require 'eventmachine'
|
||||
|
||||
class SimpleChatServer < EM::Connection
|
||||
|
||||
@@connected_clients = Array.new
|
||||
DM_REGEXP = /^@([a-zA-Z0-9]+)\s*:?\s+(.+)/.freeze
|
||||
|
||||
attr_reader :username
|
||||
|
||||
|
||||
#
|
||||
# EventMachine handlers
|
||||
#
|
||||
|
||||
def post_init
|
||||
@username = nil
|
||||
|
||||
puts "A client has connected..."
|
||||
ask_username
|
||||
end
|
||||
|
||||
def unbind
|
||||
@@connected_clients.delete(self)
|
||||
puts "[info] #{@username} has left" if entered_username?
|
||||
end
|
||||
|
||||
def receive_data(data)
|
||||
if entered_username?
|
||||
handle_chat_message(data.strip)
|
||||
else
|
||||
handle_username(data.strip)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Username handling
|
||||
#
|
||||
|
||||
def entered_username?
|
||||
!@username.nil? && !@username.empty?
|
||||
end # entered_username?
|
||||
|
||||
def handle_username(input)
|
||||
if input.empty?
|
||||
send_line("Blank usernames are not allowed. Try again.")
|
||||
ask_username
|
||||
else
|
||||
@username = input
|
||||
@@connected_clients.push(self)
|
||||
self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
|
||||
puts "#{@username} has joined"
|
||||
|
||||
self.send_line("[info] Ohai, #{@username}")
|
||||
end
|
||||
end # handle_username(input)
|
||||
|
||||
def ask_username
|
||||
self.send_line("[info] Enter your username:")
|
||||
end # ask_username
|
||||
|
||||
|
||||
#
|
||||
# Message handling
|
||||
#
|
||||
|
||||
def handle_chat_message(msg)
|
||||
if command?(msg)
|
||||
self.handle_command(msg)
|
||||
else
|
||||
if direct_message?(msg)
|
||||
self.handle_direct_message(msg)
|
||||
else
|
||||
self.announce(msg, "#{@username}:")
|
||||
end
|
||||
end
|
||||
end # handle_chat_message(msg)
|
||||
|
||||
def direct_message?(input)
|
||||
input =~ DM_REGEXP
|
||||
end # direct_message?(input)
|
||||
|
||||
def handle_direct_message(input)
|
||||
username, message = parse_direct_message(input)
|
||||
|
||||
if connection = @@connected_clients.find { |c| c.username == username }
|
||||
puts "[dm] @#{@username} => @#{username}"
|
||||
connection.send_line("[dm] @#{@username}: #{message}")
|
||||
else
|
||||
send_line "@#{username} is not in the room. Here's who is: #{usernames.join(', ')}"
|
||||
end
|
||||
end # handle_direct_message(input)
|
||||
|
||||
def parse_direct_message(input)
|
||||
return [$1, $2] if input =~ DM_REGEXP
|
||||
end # parse_direct_message(input)
|
||||
|
||||
|
||||
#
|
||||
# Commands handling
|
||||
#
|
||||
|
||||
def command?(input)
|
||||
input =~ /(exit|status)$/i
|
||||
end # command?(input)
|
||||
|
||||
def handle_command(cmd)
|
||||
case cmd
|
||||
when /exit$/i then self.close_connection
|
||||
when /status$/i then self.send_line("[chat server] It's #{Time.now.strftime('%H:%M')} and there are #{self.number_of_connected_clients} people in the room")
|
||||
end
|
||||
end # handle_command(cmd)
|
||||
|
||||
|
||||
#
|
||||
# Helpers
|
||||
#
|
||||
|
||||
def announce(msg = nil, prefix = "[chat server]")
|
||||
@@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty?
|
||||
end # announce(msg)
|
||||
|
||||
def other_peers
|
||||
@@connected_clients.reject { |c| self == c }
|
||||
end # other_peers
|
||||
|
||||
def send_line(line)
|
||||
self.send_data("#{line}\n")
|
||||
end # send_line(line)
|
||||
end
|
||||
|
||||
EventMachine.run do
|
||||
# hit Control + C to stop
|
||||
Signal.trap("INT") { EventMachine.stop }
|
||||
Signal.trap("TERM") { EventMachine.stop }
|
||||
|
||||
EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
require File.dirname(__FILE__) + '/helper'
|
||||
|
||||
EM.run do
|
||||
|
||||
# Create a channel to push data to, this could be stocks...
|
||||
RandChannel = EM::Channel.new
|
||||
|
||||
# The server simply subscribes client connections to the channel on connect,
|
||||
# and unsubscribes them on disconnect.
|
||||
class Server < EM::Connection
|
||||
def self.start(host = '127.0.0.1', port = 8000)
|
||||
EM.start_server(host, port, self)
|
||||
end
|
||||
|
||||
def post_init
|
||||
@sid = RandChannel.subscribe { |m| send_data "#{m.inspect}\n" }
|
||||
end
|
||||
|
||||
def unbind
|
||||
RandChannel.unsubscribe @sid
|
||||
end
|
||||
end
|
||||
Server.start
|
||||
|
||||
# Two client connections, that just print what they receive.
|
||||
2.times do
|
||||
EM.connect('127.0.0.1', 8000) do |c|
|
||||
c.extend EM::P::LineText2
|
||||
def c.receive_line(line)
|
||||
puts "Subscriber: #{signature} got #{line}"
|
||||
end
|
||||
EM.add_timer(2) { c.close_connection }
|
||||
end
|
||||
end
|
||||
|
||||
# This part of the example is more fake, but imagine sleep was in fact a
|
||||
# long running calculation to achieve the value.
|
||||
40.times do
|
||||
EM.defer lambda { v = sleep(rand * 2); RandChannel << [Time.now, v] }
|
||||
end
|
||||
|
||||
EM.add_timer(5) { EM.stop }
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
require File.dirname(__FILE__) + '/helper'
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
require File.dirname(__FILE__) + '/helper'
|
||||
|
||||
EM.run do
|
||||
array = (1..100).to_a
|
||||
|
||||
tickloop = EM.tick_loop do
|
||||
if array.empty?
|
||||
:stop
|
||||
else
|
||||
puts array.shift
|
||||
end
|
||||
end
|
||||
|
||||
tickloop.on_stop { EM.stop }
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
require File.dirname(__FILE__) + '/helper'
|
||||
|
||||
class TickCounter
|
||||
attr_reader :start_time, :count
|
||||
|
||||
def initialize
|
||||
reset
|
||||
@tick_loop = EM.tick_loop(method(:tick))
|
||||
end
|
||||
|
||||
def reset
|
||||
@count = 0
|
||||
@start_time = EM.current_time
|
||||
end
|
||||
|
||||
def tick
|
||||
@count += 1
|
||||
end
|
||||
|
||||
def rate
|
||||
@count / (EM.current_time - @start_time)
|
||||
end
|
||||
end
|
||||
|
||||
period = 5
|
||||
EM.run do
|
||||
counter = TickCounter.new
|
||||
EM.add_periodic_timer(period) do
|
||||
puts "Ticks per second: #{counter.rate} (mean of last #{period}s)"
|
||||
counter.reset
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||
require 'eventmachine'
|
||||
Reference in New Issue
Block a user