Created
March 11, 2010 21:31
-
-
Save tmm1/329682 to your computer and use it in GitHub Desktop.
EM Chat Server Demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'eventmachine' | |
require 'em-http' # gem install em-http-request | |
require 'yajl' # gem install yajl-ruby | |
class String | |
def bold | |
"\033[1m#{self}\033[0m" | |
end | |
end | |
module ChatClient | |
def post_init | |
@buf = '' | |
@name = "anonymous_#{ChatClient.client_num+=1}" | |
@sid = ChatClient.channel.subscribe do |msg| | |
send_msg(msg) | |
end | |
send_header | |
send_prompt | |
ChatClient.channel << "#{@name.bold} has joined.\n" | |
end | |
def unbind | |
ChatClient.channel.unsubscribe(@sid) | |
ChatClient.channel << "#{@name.bold} has left.\n" | |
end | |
def receive_data data | |
@buf << data | |
quit and return if @buf =~ /(\006|\004)/ # ctrl+c or ctrl+d | |
while line = @buf.slice!(/(.+)\r?\n/) | |
p [@name, line] | |
send_prompt | |
if line =~ %r|^/nick (.+)| | |
new_name = $1.strip[0..12] | |
ChatClient.channel << "#{@name.bold} is now known as #{new_name.bold}\n" | |
@name = new_name | |
send_prompt | |
elsif line =~ %r|^/me (.+)| | |
ChatClient.channel << "#{@name.bold} #{$1.strip}\n" | |
elsif line =~ %r|^/say (.+)| | |
send_msg "\033[37mAdding #{$1.strip.bold} to the say queue at position #{ChatClient.say_queue.size+1}\033[0m\n" | |
ChatClient.say_queue.push "#{@name} said #{$1.strip}" | |
elsif line =~ %r|^/quit| | |
quit | |
elsif line =~ /^\e/ # ignore escape sequences | |
send_prompt | |
elsif !line.strip.empty? | |
ChatClient.channel << "#{@name.bold}: #{line.gsub(/[^[:print:]]/,'')}\n" | |
end | |
end | |
end | |
private | |
def send_header | |
send_data "\033[2;23r" | |
send_data "\033[2J" | |
send_data "\033[1H" | |
header = "Welcome to the EventMachine Chat Demo (/nick, /me, /say, /quit)".center(80) | |
send_data "\033[32m#{header}\033[0m" | |
end | |
def send_msg msg | |
send_data "\0337" | |
send_data "\033M" | |
send_data "\033[23;1H" | |
send_data msg | |
send_data "\0338" | |
end | |
def send_prompt | |
send_data "\033[24H" | |
send_data "\033[2K" | |
send_data "\033[1m" | |
send_data @name | |
send_data "\033[0m: " | |
end | |
def quit | |
send_data "\033[2J" | |
send_data "\033[1;1H" | |
header = "Check out http://gist.github.com/329682 for the source to the EM chat server".center(80) | |
send_data "\033[32m#{header}\033[0m" | |
send_data "\033[r" | |
send_data "\033[3;1H" | |
close_connection_after_writing | |
end | |
@client_num = 0 | |
class << self | |
attr_accessor :client_num | |
end | |
def ChatClient.channel | |
@channel ||= EM::Channel.new | |
end | |
def ChatClient.say_queue | |
@say_queue ||= begin | |
q = EM::Queue.new | |
# pop off items from the queue one at a time, and pass them to `say` | |
processor = proc{ |msg| | |
ChatClient.channel << "\033[37mSaying: #{msg.bold}\033[0m\n" | |
EM.system("say", msg) do |out, status| | |
p [:say, msg, status] | |
q.pop(&processor) | |
end | |
} | |
# pop off the first item | |
q.pop(&processor) | |
q | |
end | |
end | |
end | |
class TwitterStream | |
def initialize(user, pass, tags, &blk) | |
raise ArgumentError, 'block required' unless blk | |
http = EM::HttpRequest.new( | |
"http://stream.twitter.com/1/statuses/filter.json?track=#{tags.join(',')}" | |
).get( | |
:head => {'authorization' => [user, pass]} | |
) | |
parser = Yajl::Parser.new(:symbolize_keys => true) | |
parser.on_parse_complete = blk | |
http.stream do |data| | |
parser << data | |
end | |
end | |
end | |
EM.run{ | |
EM.start_server '0.0.0.0', 1337, ChatClient | |
EM::PeriodicTimer.new(90) do | |
ChatClient.channel << "\033[31mThe time is now #{Time.now}\033[0m\n" | |
end | |
TwitterStream.new('USERNAME', 'PASSWORD', %w[ railsconf eventmachine ]) do |tweet| | |
name, msg = tweet[:user][:screen_name], tweet[:text] | |
p [:tweet, name, msg] | |
ChatClient.channel << "\033[34;1m@#{name}\033[0m: #{msg}\n" | |
end | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment