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離開了聊天室乔夯!"砖织。
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