Skip to content

Commit

Permalink
Add simple chat based on EventMachine with Couchbase logger
Browse files Browse the repository at this point in the history
Change-Id: If0a80f31d87ba632ff6510e2175c340dfcc876ba
Reviewed-on: http://review.couchbase.org/24480
Tested-by: Sergey Avseyev <sergey.avseyev@gmail.com>
Reviewed-by: Sergey Avseyev <sergey.avseyev@gmail.com>
  • Loading branch information
avsej committed Feb 8, 2013
1 parent 89f76f3 commit f759a6f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
7 changes: 7 additions & 0 deletions examples/chat-em/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
source :rubygems

gem 'eventmachine'

# couchbase dependencies
gem 'yaji'
gem 'multi_json'
45 changes: 45 additions & 0 deletions examples/chat-em/README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Chat Demo

This is simple demo of the chat built on EventMachine, and using
Couchbase to store logs.

# Quick Start and Usage

Navigate to the example directory and install dependencies:

$ cd examples/chat-em
$ bundle install

Execute the server

$ ruby ./server.rb
Hi, this is simple chat server based on EventMachine.
To join, just use your telnet or netcat clients to connect to
port 9999 on this machine. Press Ctrl-C to stop it.

Use telnet to join the chat

$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
*** What is your name?
avsej
*** Hi, avsej!
Hi everyone in this chat

The server will broadcast all your messages and record any event to
the Couchbase server. If your server hosted not on the localhost or
using bucket different from "default" you might want to change the
connection options at the bottom of the `server.rb`, for example in
this case it will connect to the bucket "protected" with password
"secret".

Couchbase.connection_options = {
:async => true,
:engine => :eventmachine,
:bucket => "protected",
:password => "secret"
}

Happy hacking!
82 changes: 82 additions & 0 deletions examples/chat-em/server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env ruby
["/../../lib", "/.."].each do |path|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + path))
end

require 'bundler'
Bundler.require

require 'couchbase'

class ChatServer < EM::Connection

@@clients = []

def log(message, author = nil)
Couchbase.bucket.incr("log:key", :initial => 1) do |res|
entry = {
'time' => Time.now.utc,
'author' => author || "[system]",
'message' => message
}
Couchbase.bucket.set("log:#{res.value}", entry)
end
end

def post_init
@username = nil
send_data("*** What is your name?\n")
end

def receive_data(data)
if @username
broadcast(data.strip, @username)
else
name = data.gsub(/\s+|[\[\]]/, '').strip[0..20]
if name.empty?
send_data("*** What is your name?\n")
else
@username = name
@@clients.push(self)
broadcast("#{@username} has joined")
send_data("*** Hi, #{@username}!\n")
end
end
end

def unbind
@@clients.delete(self)
broadcast("#{@username} has left") if @username
end

def broadcast(message, author = nil)
prefix = author ? "<#{@username}>" : "***"
log(message, author)
@@clients.each do |client|
unless client == self
client.send_data("#{prefix} #{message}\n")
end
end
end

end

EventMachine.run do
# hit Control + C to stop
Signal.trap("INT") { EventMachine.stop }
Signal.trap("TERM") { EventMachine.stop }

Couchbase.connection_options = {:async => true, :engine => :eventmachine}
Couchbase.bucket.on_connect do |res|
if res.success?
puts(<<-MOTD.gsub(/^\s+/, ''))
Hi, this is simple chat server based on EventMachine.
To join, just use your telnet or netcat clients to connect to
port 9999 on this machine. Press Ctrl-C to stop it.
MOTD
EventMachine.start_server("0.0.0.0", 9999, ChatServer)
else
puts "Cannot connect to Couchbase Server: #{res.error}"
end
end
end

0 comments on commit f759a6f

Please sign in to comment.