node.js简易聊天室
转自:http://huli.logdown.com/posts/261051-node-js-socketio-to-create-super-simple-chat-room
最近在研究node.js,由於它是單線程的,所以適合的場景是:連接數多,但是每個連接做的事情都不會佔用大量資源。
在這樣的前提之下,聊天室就是一個很好的範例,可以同時容納很多人,但每個人做的事情(發送訊息)都很快速就可以完成。
而socket.io就是一套可以同時使用在server跟client的library,而且使用方法非常簡單
http://socket.io/get-started/chat/
這是官方的基本教學,看著這個做其實很快就可以上手
只是我有碰到一些問題,所以後來拿這份範例去改了一下,加了一些新功能
先來介紹一下怎麼使用socket.io
直接看code或許會比較容易明瞭
//app.js
io.on('connection', function(socket){
//新user
socket.on('add user',function(msg){
socket.username = msg;
console.log("new user:"+msg+" logged.");
io.emit('add user',{
username: socket.username
});
});
});
在有新的client連入的時候,就會執行到connection
的callback function,會傳入一個socket
,可以利用這個socket跟這個client溝通
而socket.on
就是新增一個監聽事件,就像jQuery的$('#btn').on('click',function(...))
那樣
在上面的程式碼中,我們新增了一個add user
的事件,等待client端觸發。而這個事件是有新使用者連進來的時候,會傳入它的username,在這邊把這個資訊附加在socket
上面,識別這個使用者。
而io.emit
就是送出資料給所有連線的client,add user
則是事件名稱,第二個參數是要送出的資料
針對上面這段server的code,如果寫在client(html)上面,大致上會長這樣
//index.html
var socket = io();
var name = prompt("請輸入暱稱","guest");
socket.emit("add user",name);
socket.on('add user',function(data){
appendMessage(data.username+"已加入");
});
在用戶輸入name以後,利用socket.emit
傳訊息給server,觸發server的socket.on('add user',...)
接著再監聽add user
事件,每當server傳通知來說有新的使用者連入的時候,就在畫面上新增資訊
在這邊要特別提一下
有一種作法是,在client的操作都直接呈現結果,例如說你發送訊息,就直接$(#msg).append(msg)
之類的;另外一種作法是,一律監聽從socket發送過來的事件,再去做處理。
第一種作法在server端的時候,我們原本用的是io.emit
發送訊息,但是在這邊不能這樣用
為什麼?因為會造成重複操作
1.使用者aa輸入訊息:你好
2.送出訊息
3.畫面呈現出:你好
4.使用者aa收到socket的事件,有人傳送訊息:你好
5.新增訊息
6.畫面呈現出:你好 你好
所以在server端的時候,要避免發送訊息給「自己」
在實作上面是socket.broadcast.emit(...)
,就可以發送訊息給「除了自己之外的所有socket」
而io.emit
則是直接送給所有的socket
我一開始在測試的時候,用了socket.broadcast.emit(...)
,html裡面又沒有直接呈現操作的結果,害我一直很疑惑,為什麼socket永遠收不到server傳來的事件....不管傳什麼訊息就沒有回傳回來
反正簡單來說就是,
要發送事件用socket.emit
或是io.emit(server端)
,要接收事件用socket.on
,就是這麼簡單
你只要自己定義一些事件名稱跟寫收到事件後要執行的code即可
這邊是一個小範例
可以發送訊息,可以取暱稱,可以通知說誰誰誰加入或離開
還滿陽春的,但是我想應該足夠幫助對於socket.io的理解了
想要更多功能的範例可參考官方範例
原始碼:https://github.com/aszx87410/nodejs_simple_chatroom
以下属于折腾部分(使用nginx反代node.js,为了使全站都使用到https
以及不想改防火墙设置)
- node.js安装与运行
#以下操作基于centos6.5
#安装nodejs
yum install nodejs
#下载源码
wget https://github.com/aszx87410/nodejs_simple_chatroom/archive/master.zip
unzip master.zip
#运行
node app.js
#常驻运行
nohup node app.js &
#取消常驻运行
kill -pid
- nginx反代node.js
#添加
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
#server内添加
server{
#将/chat/这个二级目录反代给node.js
location /chat/ {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
#如果不是使用的二级目录,下面的就可以不需要了
location /socket.io/ {
proxy_pass http://127.0.0.1:3000/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
- 最终演示地址:
https://www.lijunx.cn/chat/