-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathchat-ws.rb
More file actions
84 lines (75 loc) · 2.78 KB
/
chat-ws.rb
File metadata and controls
84 lines (75 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require './em-websocket/lib/em-websocket'
require 'cgi'
require 'uri'
require 'json'
#require 'sinatra'
require 'thin'
require 'logger'
require 'erb'
EventMachine.run {
@logger = Logger.new('log/chat.log')
@paint_channels = {}
@chat_channels = {}
@members = {}
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080, :debug => false) do |ws|
ws.onopen {
room_name = ws.request['Query']['room'].force_encoding('UTF-8')
user_name = ERB::Util.h(ws.request['Query']['user']).force_encoding('UTF-8')
# chat は /chat, お絵かきは /paint
case URI.split(ws.request['Path'])[5]
when '/chat'
# チャンネルを取得(or作成)して、そこに入る
channel = @chat_channels[room_name] || (@chat_channels[room_name] = EM::Channel.new)
sid = channel.subscribe { |msg| ws.send msg.force_encoding("ASCII-8BIT") }
members = @members[room_name] || (@members[room_name] = {})
members[sid] = user_name
ws.onmessage { |msg|
msg.force_encoding('UTF-8')
channel.push({
:user => user_name,
:comment => ERB::Util.h(msg),
:time => Time.now.strftime('%H:%M'),
:user_id => sid
}.to_json)
}
ws.onclose {
members.delete(sid)
channel.push({
:user => ERB::Util.h("システム"),
:comment => "#{user_name}さんがチャットから離脱しました。",
:time => Time.now.strftime('%H:%M'),
:user_id => 0,
:members => members.values,
}.to_json)
channel.unsubscribe(sid)
}
channel.push({
:user => ERB::Util.h("システム"),
:comment => "#{user_name}さんがチャットに参加しました。",
:time => Time.now.strftime('%H:%M'),
:user_id => 0,
:members => members.values,
}.to_json) #<#{sid}> "
when '/paint'
# チャンネルを取得(or作成)して、そこに入る
channel = @paint_channels[room_name] || (@paint_channels[room_name] = EM::Channel.new)
members = @members[room_name] || (@members[room_name] = [])
sid = channel.subscribe { |msg| ws.send msg }
ws.onmessage { |msg| channel.push(msg) }
ws.onclose { channel.unsubscribe(sid) }
# 自分が2人目以降なら、今までのデータをリクエスト
if 1 < members.size
channel.push({
:sync_send => true,
:sync_from_user => CGI.escape(members[members.keys.min]),
:sync_to_user => CGI.escape(user_name),
}.to_json)
end
end
}
end
@logger.info("Server started")
}