undefined

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;
    }
}