# 4. 實現簡易聊天室
#### 1. 介紹
這篇文章介紹一下如何實現一個簡易的聊天室。

#### 2. 客戶端
首先是界面。
新建一個index.html文件,內容如下:
```
<html>
<head>
<meta charset="UTF-8" content="text/html" http-equiv="Content-Type">
<title>websocket chat</title>
<script src="http://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script>
<script src="./main.js"></script>
</head>
<body>
<h1>websocket chat</h1>
<div>
<input id="name" size="15" type="text" value="NAME">
<input id="message" size="80" type="text" value="hello hello">
<input id="btn_post" type="button" value="post">
</div>
<ul id="chat"></ul>
</body>
</html>
```
新建main.js文件,內容如下:
```
var ws = new WebSocket("ws://localhost:8080");
ws.onmessage = function(e){
print(e.data);
};
ws.onopen = function(e){
log("websocket open");
console.log(e);
};
ws.onclose = function(e){
log("websocket close");
console.log(e);
};
$(function(){
$("#btn_post").click(post);
$("#message").keydown(function(e){
if(e.keyCode == 13) post();
});
});
var post = function(){
var name = $("#name").val();
var mes = $("#message").val();
ws.send(name+" : "+mes);
$("input#message").val("");
};
var log = function(msg){
console.log(msg);
$("#chat").prepend($("<li>").text("[log] "+msg));
};
var print = function(msg){
$("#chat").prepend($("<li>").text(msg));
};
```
post函數中有一句`ws.send(name+" : "+mes);`發送到服務器端,這個是發送聊天語句的。
#### 3. 服務器端
現在添加服務器端代碼。
新建echo\_server.rb文件,內容如下:
```
#!/usr/bin/env ruby
require 'eventmachine'
require 'websocket-eventmachine-server'
PORT = (ARGV.shift || 8080).to_i
EM::run do
@channel = EM::Channel.new
puts "start websocket server - port:#{PORT}"
WebSocket::EventMachine::Server.start(:host => "0.0.0.0", :port => PORT) do |ws|
ws.onopen do
sid = @channel.subscribe do |mes|
ws.send mes
end
puts "<#{sid}> connect"
@channel.push "hello new client <#{sid}>"
ws.onmessage do |msg|
puts "<#{sid}> #{msg}"
@channel.push "<#{sid}> #{msg}"
end
ws.onclose do
puts "<#{sid}> disconnected"
@channel.unsubscribe sid
@channel.push "<#{sid}> disconnected"
end
end
end
end
```
瀏覽器和服務器端一直會維持鏈接,`ws.send mes`表示發送信息給瀏覽器,只要瀏覽器與服務器端維持著鏈接,就會收到信息,相當于廣播了。
運行服務器。
```
$ ruby echo_server.rb
```
接著打開兩個瀏覽器,都分別運行index.html文件,就可以看到效果了。
本篇完結。
下一篇:[websocket之rack hijack的原理及tubesock(五)](http://www.rails365.net/articles/websocket-zhi-rack-hijack-de-yuan-li-ji-tubesock-wu)