Node.js(Express4.x)搭建聊天室1——基本框架

0.目標(biāo)

不得不說辈挂,用Node.js搭建一個即時的聊天室是一件很cool的事情激才。今天就使用socket.io來搭建一個簡易的聊天室缓醋。

我把搭建聊天室的步驟分成了幾個部分,請按順序閱讀:

獲取代碼
Node.js(Express4.x)搭建聊天室1——基本框架
Node.js(Express4.x)搭建聊天室2——消息發(fā)送與監(jiān)聽
Node.js(Express4.x)搭建聊天室3——完善網(wǎng)頁


1.部署

1.1 部署Express

如果不知道如何部署瞳氓,可參照: 部署Express


1.2 服務(wù)端安裝socket.io

npm install socket.io --save


2.服務(wù)端

2.1 創(chuàng)建一個socket.io模塊

我不打算按照socket.io官網(wǎng)的介紹那樣,把socket.io寫在app.js(Express3.x)或者bin/www(Express4.x)里面栓袖。因?yàn)槿绻@樣做了匣摘,總感覺修改一點(diǎn)代碼就得把整個應(yīng)用的入口文件給改了;在我看來裹刮,入口文件就應(yīng)該加載各個模塊等音榜,而不是處理某些具體的事務(wù);并且這樣做也不利于代碼的模塊化捧弃。

因此赠叼,參考了Mike Cantlon, Marc Harter, T.J.Holowaychuk, Nathan Rajlich所著的《Node.js實(shí)戰(zhàn)》一書,我把這部分代碼分離出來,僅在app.js(Express3.x)或者bin/www(Express4.x)文件中加載這個模塊梅割。

在根目錄下創(chuàng)建一個文件夾model霜第,并在文件夾中新建一個文件:chatroom.js。代碼如下:

/**
 * @Name    :  chatroom.js
 * @Module  :  Socket.io Module
 * @Author  :  Linxiaozhou
 * @Date    :  2016.09.20
 * @Ref1    :  Node.js in Action (Mike Cantlon, Marc Harter, T.J.Holowaychuk, Nathan Rajlich)
 * @Ref2    :  http://socket.io/docs/
 * @Ref3    :  https://github.com/socketio/socket.io/blob/master/examples/chat/index.js
 * @Brief   :  Process chatroom through socket.io
 */

var socketio = require('socket.io');
var io;
var guest_num = 0;

// 外部接口
exports.listen = function(server) {
    
    io = socketio(server);
    
    io.on('connection', function (socket) {
      var addedUser = false;
      
      
      /* *************** 用戶emit消息"join"時户辞,響應(yīng) *************** */
      socket.on('join', function (username) {
        if (addedUser) return;
          
        // 用戶信息存儲在socket會話中
        socket.username = username;
        ++guest_num;
        addedUser = true;
        
        // 告知用戶登錄成功
        socket.emit('login', {
            username: socket.username,
            numUsers: guest_num
        });

        // 廣播告知所有用戶
        socket.broadcast.emit('user_joined', {
            username: socket.username,
            msg: "歡迎 "+socket.username + " 進(jìn)入聊天室",
            type: "BROADCAST",
            numUsers: guest_num
        });
      });
      
      
      /* *************** 用戶離開 *************** */
      socket.on('disconnect', function () {
        if (addedUser) {
          --guest_num;

          // 告知所有用戶
          socket.broadcast.emit('user_left', {
            username: socket.username,
            msg: socket.username + "離開了聊天室!",
            type: "BROADCAST",
            numUsers: guest_num
          });
        }
      });
      
      
      /* *************** 更多 *************** */
      // 在這里添加更多監(jiān)聽的消息
      // ...
      
      
    });
    
};

這部分代碼可供外部調(diào)用癞谒,需要傳入http模塊的server信息底燎。這部分代碼實(shí)現(xiàn)了這些功能:

  • 當(dāng)客戶端發(fā)送(emit)出“join”消息時,服務(wù)器會把隨此消息發(fā)來的username存入socket會話中弹砚,并增加當(dāng)前聊天室的總?cè)藬?shù)guest_num双仍,然后發(fā)送消息“l(fā)ogin”告知該用戶登錄成功,并廣播消息“user_joined”告知所有用戶桌吃。
  • 當(dāng)用戶離開聊天室朱沃,服務(wù)器會向所有的用戶發(fā)出廣播消息“user_left”。

更多功能會在后續(xù)添加茅诱。


2.2 在入口文件引入chatroom模塊

前面說過逗物,為了分離chatroom模塊,我們在model文件夾下新建了一個chatroom.js文件來存放相關(guān)模型代碼瑟俭。然后需要在app.js(Express3.x)或者bin/www(Express4.x)文件中加載這個模塊翎卓。我使用的是Express4.x,所以要在bin/www文件中添加如下代碼:

// 在var server = http.createServer(app);代碼后面添加摆寄!

/**
 * Socket.io for chatroom
 */
var chatroom = require('../model/chatroom');
chatroom.listen(server);

3.客戶端

打開views/index.jade失暴,替換成下面的代碼:

doctype html
html
    head
        title= title
        link(rel='stylesheet', href='/stylesheets/style.css')
    body
        h1 socket.io聊天室
        p#status
        
    // 加載socket.io模塊
    script(src='https://cdn.socket.io/socket.io-1.4.5.js')
        
    script.
        //啟動
        var socket = io.connect('http://127.0.0.1:3000');
        
        //發(fā)送消息
        socket.emit('join', "Mike", function (data) {
            console.log(data);
        });
        
        //監(jiān)聽
        socket.on('login', function (data) {
            console.log(data);
        });
        
        socket.on('user_joined', function (data) {
            console.log(data);
        });
        
        socket.on('user_left', function (data) {
            console.log(data);
        });
        
        // 更多
        // 添加更多的消息發(fā)送或監(jiān)聽
        // ...

注意到我們在發(fā)射消息的時候(socket.emit('join', "Mike", function (data) {});),除了“join”消息微饥,還傳入了一個參數(shù)“Mike”逗扒;查看服務(wù)端代碼可知,這個會被當(dāng)作用戶的昵稱(socket.on('join', function (username) {});)欠橘。

由此可以延展一下:在調(diào)用io.connect('http://127.0.0.1:3000');創(chuàng)建連接之前是不是可以先讓用戶輸入昵稱矩肩,然后再發(fā)送加入的消息socket.emit('join', "<用戶輸入的昵稱>", function (data) {});?這也是為什么我們看到很多Demo都會要我們先輸入nickname的原因吧简软。


4.測試

4.1 加入

至此蛮拔,我們完成了服務(wù)端的部署以及客戶端的提供,可以開始測試了痹升。

開啟服務(wù)建炫,打開一個瀏覽器A,訪問http://127.0.0.1:3000疼蛾, 打開另一個瀏覽器B肛跌,也訪問http://127.0.0.1:3000, 按F12查看打印即可。

測試

瀏覽器A是先打開的衍慎,可以看到有兩個消息转唉,第一個是告知該用戶登錄成功的消息,第二個是瀏覽器B加入后廣播的消息稳捆,告知瀏覽器A的用戶有新用戶加入了赠法。


4.2 離開

我們關(guān)閉瀏覽器B,此時瀏覽器A打開消息"Mike離開了聊天室乔夯!"砖织。

瀏覽器B用戶離開

5.更多

聊天室功能自然是要發(fā)消息的,所以接下來末荐,還要允許用戶發(fā)消息侧纯、接收消息。這些內(nèi)容我不準(zhǔn)備在這一節(jié)來說明甲脏,因?yàn)榱奶焓业目蚣芤呀?jīng)搭好了眶熬!要更進(jìn)一步,請看下面幾節(jié):

Node.js(Express4.x)搭建聊天室2——消息發(fā)送與監(jiān)聽
Node.js(Express4.x)搭建聊天室3——完善網(wǎng)頁


原創(chuàng)文章块请,未經(jīng)許可娜氏,請勿轉(zhuǎn)載
作者:Mike的讀書季
日期:2016.09.20
QQ:1139904786
Blog:http://blog.csdn.net/kkdestiny

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市负乡,隨后出現(xiàn)的幾起案子牍白,更是在濱河造成了極大的恐慌,老刑警劉巖抖棘,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茂腥,死亡現(xiàn)場離奇詭異,居然都是意外死亡切省,警方通過查閱死者的電腦和手機(jī)最岗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朝捆,“玉大人般渡,你說我怎么就攤上這事≤脚蹋” “怎么了驯用?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長儒老。 經(jīng)常有香客問我蝴乔,道長,這世上最難降的妖魔是什么驮樊? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任薇正,我火速辦了婚禮片酝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挖腰。我一直安慰自己雕沿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布猴仑。 她就那樣靜靜地躺著审轮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宁脊。 梳的紋絲不亂的頭發(fā)上断国,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機(jī)與錄音榆苞,去河邊找鬼。 笑死霞捡,一個胖子當(dāng)著我的面吹牛坐漏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碧信,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赊琳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了砰碴?” 一聲冷哼從身側(cè)響起躏筏,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呈枉,沒想到半個月后趁尼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猖辫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年酥泞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啃憎。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡芝囤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辛萍,到底是詐尸還是另有隱情悯姊,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布贩毕,位于F島的核電站悯许,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏耳幢。R本人自食惡果不足惜岸晦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一欧啤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧启上,春花似錦邢隧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至包券,卻和暖如春纫谅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背溅固。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工付秕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侍郭。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓询吴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亮元。 傳聞我的和親對象是個殘疾皇子猛计,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容