-
-
Save katahirado/2876111 to your computer and use it in GitHub Desktop.
require 'sinatra' | |
get '/' do | |
'Hello World' | |
end |
<html> | |
<head> | |
<script src='js/swfobject.js'></script> | |
<script src='js/FABridge.js'></script> | |
<script src='js/web_socket.js'></script> | |
<script> | |
var Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket; | |
var ws; | |
function reciveDataSpace(string) { | |
var element = document.getElementById("reciveDataSpace"); | |
var p = document.createElement("p"); | |
p.appendChild(document.createTextNode(string)); | |
element.appendChild(p); | |
} | |
function loginState(string) { | |
var element = document.getElementById("loginState"); | |
element.innerHTML = "<p>" + string + "</p>"; | |
} | |
function init() { | |
Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket; | |
ws = new Socket("ws://localhost:8080/"); | |
ws.onmessage = function(evt) { | |
if("[CreateLoginUserCmd_OK]" == evt.data){ | |
loginState("login"); | |
changeloginState(); | |
} | |
else if("[CreateLoginUserCmd_NG]" == evt.data){ | |
loginState("The login name is already used. "); | |
} | |
else{ | |
reciveDataSpace("Message: " + evt.data); | |
} | |
}; | |
ws.onclose = function() { reciveDataSpace("socket closed"); }; | |
ws.onopen = function() { | |
reciveDataSpace("connected..."); | |
} | |
} | |
function sendMessage(){ | |
var sendMsg = document.getElementById("message"); | |
var name = document.getElementById("loginName"); | |
if(sendMsg.value == "") return; | |
if(name.value == "") return; | |
ws.send("[" + name.value + "]:" + sendMsg.value); | |
sendMsg.value = ""; | |
} | |
function sendLogin(){ | |
loginState(""); | |
var name = document.getElementById("loginName"); | |
if(name.value == "") { | |
loginState("Name is empty."); | |
return; | |
} | |
ws.send("[CreateLoginUserCmd]:" + name.value); | |
} | |
function changeloginState(){ | |
var name = document.getElementById("loginName"); | |
if(name.value == "") return; | |
var login = document.getElementById("buttonLogin"); | |
login.disabled = true; | |
var name = document.getElementById("loginName"); | |
name.disabled = true; | |
var sendBtn = document.getElementById("buttonSend"); | |
sendBtn.disabled = false; | |
}; | |
</script> | |
</head> | |
<body onload="init();"> | |
<div> | |
ログイン名: | |
<INPUT TYPE="text" id="loginName" size="20" value=""> | |
<INPUT TYPE="button" id="buttonLogin" VALUE="ログイン" onClick="sendLogin()"> | |
</div> | |
<div id="loginState"><p></p></div> | |
<div> | |
送信メッセージ: | |
<INPUT TYPE="text" id="message" size="20" value=""> | |
<INPUT TYPE="button" id="buttonSend" VALUE="送信" disabled="true" onClick="sendMessage()"> | |
</div> | |
<div> | |
受信データ | |
<div id="reciveDataSpace"></div> | |
</div> | |
</body> | |
</html> |
require './app' | |
run Sinatra::Application |
#Gemfile | |
gem "sinatra" | |
gem "em-websocket" | |
#Gemfile.lock | |
GEM | |
specs: | |
addressable (2.2.8) | |
em-websocket (0.3.6) | |
addressable (>= 2.1.1) | |
eventmachine (>= 0.12.9) | |
eventmachine (0.12.10) | |
rack (1.4.1) | |
rack-protection (1.2.0) | |
rack | |
sinatra (1.3.2) | |
rack (‾> 1.3, >= 1.3.6) | |
rack-protection (‾> 1.2) | |
tilt (‾> 1.3, >= 1.3.3) | |
tilt (1.3.3) | |
PLATFORMS | |
ruby | |
DEPENDENCIES | |
em-websocket | |
sinatra | |
#/usr/bin/env ruby | |
require 'rubygems' | |
require 'em-websocket' | |
# チャット用モジュール ユーザー管理を追加 | |
module ChatModule | |
# ログイン要求コマンド | |
CMD_LOGIN = "[CreateLoginUserCmd]" | |
CMD_RETURN_LOGIN_OK = "[CreateLoginUserCmd_OK]" | |
CMD_RETURN_LOGIN_NG = "[CreateLoginUserCmd_NG]" | |
# ユーザー管理 | |
@@connected_clients = Hash.new | |
# 受信したメッセージがログイン要求かどうか | |
def loginMessage?(msg) | |
msgArray = msg.strip.split(":") | |
1 < msgArray.size && msgArray[0].include?(CMD_LOGIN) | |
end | |
# 接続ユーザー全員にメッセージを送る | |
def sendBroadcast(msg) | |
return if msg.empty? | |
@@connected_clients.each_value { |c| c.send(msg) } | |
puts msg | |
end | |
# ログイン処理 | |
def login(msg) | |
msgArray = msg.strip.split(":") | |
name = msgArray[1][0...(msgArray[1].size-1)] | |
if @@connected_clients.has_key?(name) == false | |
@loginName = name | |
@@connected_clients[@loginName] = self | |
send(CMD_RETURN_LOGIN_OK) | |
puts "Login name is #{@loginName}" | |
else | |
send(CMD_RETURN_LOGIN_NG) | |
end | |
end | |
#ログアウト処理 | |
def logout() | |
if @loginName && @loginName.empty? == false | |
msg = "[#{@loginName}] is logout." | |
puts msg | |
@@connected_clients.delete(@loginName) | |
@@connected_clients.each_value { |c| c.send(msg) } | |
end | |
puts "WebSocket closed" | |
end | |
end | |
EM::WebSocket.start(:host => "0.0.0.0", :port => 8080) { |ws| | |
ws.extend(ChatModule) | |
ws.onopen{ | |
ws.send("Welcome! Please login!") | |
} | |
ws.onmessage { |msg| | |
return if msg.strip.size < 1 | |
if ws.loginMessage?(msg) | |
ws.login(msg) | |
else | |
ws.sendBroadcast(msg) | |
end | |
} | |
ws.onclose{ | |
ws.logout | |
} | |
ws.onerror{ |e| | |
ws.logout | |
puts "Error: #{e.message}" | |
} | |
} |
やったこと。
Sinatraでのデプロイ確認。
Sinatraのpublicに静的ファイル置いてchat.htmlが表示されるのを確認。
sshでログインして、bundle exec ruby Websocket.rb
/home/sqale/current/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:572:in start_tcp_server': no acceptor (RuntimeError) from /home/sqale/current/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:572:in
start_server'
from /home/sqale/current/vendor/bundle/ruby/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/websocket.rb:14:in block in start' from /home/sqale/current/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in
call'
from /home/sqale/current/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in run_machine' from /home/sqale/current/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in
run'
from /home/sqale/current/vendor/bundle/ruby/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/websocket.rb:9:in start' from WebSocketChat.rb:54:in
WebSocket.rbとchat.htmlは下記のコードそのままです。
https://github.com/icchi/WebSocketChat
chat.htmlはpublic/ディレクトリを用意して、その下に配置しています。