我建置的專案如下圖
這篇想法就是透過WebSocket來建立通訊
將接收到的值以JSON方式存進Redis的list內
並透過Broadcast filter到的訊息將其加入至聊天室內
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
www.js
#!/usr/bin/env node
var app = require('../app');
var http = require('http').Server(app);
var io = require('socket.io')(http);
var redis = require('redis');
const redisClient = redis.createClient(6379, '192.168.126.128');
io.on('connection', function(socket) {
socket.on('msg', function(data) {
socket.broadcast.emit('msg', data);
redisClient.lpush('messages', JSON.stringify(data));
redisClient.ltrim('messages', 0, 99);
});
socket.on('join', function(nickname) {
socket.nickname = nickname;
socket.broadcast.emit('notice', nickname + ' has joined the chat.');
});
socket.on('disconnect', function() {
socket.broadcast.emit('notice', socket.nickname + ' has left the chat.');
});
});
http.listen(3000);
client.js
$(document).ready(function() {
var socket = io(), nickname, msgList = $('#messages');
if('localStorage' in window && localStorage.getItem('name')) {
nickname = localStorage.getItem('name');
} else {
nickname = prompt('input your nickname');
if('localStorage' in window) {
localStorage.setItem('name', nickname);
}
}
socket.emit('join', nickname);
var newMessage = function(data) {
var who = $('<div class="who">').text(data.nickname),
when = $('<div class="when">').text(new Date().toString().substr(0, 24)),
msg = $('<div class="msg">').text(data.msg),
header = $('<div class="header clearfix">').append(who).append(when),
li = $('<li>').append(header).append(msg);
msgList.prepend(li);
};
$('form').submit(function(e) {
var msgField = $('#msg'),
data = { msg: msgField.val(), nickname: nickname, when: new Date() };
e.preventDefault();
socket.emit('msg', data);
newMessage(data);
msgField.val('');
});
socket.on('msg', function(data) {
newMessage(data);
});
socket.on('notice', function(msg) {
msgList.prepend($('<div class="notice">').text(msg));
});
});
index.pug
extends layout
block content
h1=title
form
input(id='msg' type='text' autocomplete='off' autofocus)
button(type='submit') send
ul#messages
- for(var i=0,ln =messages.length;i<ln;i++)
li
.header.clearfix
.who= messages[i].nickname
.when= new Date(messages[i].when).toString().substr(0, 24)
.msg= messages[i].msg
參考資料:
http://zh.wikipedia.org/wiki/WebSocket
http://usherchen.blogspot.tw/2013/07/html-websocket-sample-with-php-server.html
http://kheresy.wordpress.com/2013/04/02/html5-websocket-client/
https://developer.mozilla.org/zh-TW/docs/WebSockets/Writing_WebSocket_client_applications
http://blog.mukispace.com/websocket-simple-introduce-and-use/
http://www.mrdoob.com/projects/multiuserpad/
http://www.websocket.org/echo.html
http://msdn.microsoft.com/zh-tw/library/ie/hh673567(v=vs.85).aspx
http://dev.w3.org/html5/websockets/
http://dev.w3.org/html5/websockets/#ping-and-pong-frames
http://dev.w3.org/html5/websockets/#feedback-from-the-protocol
https://www.ibm.com/developerworks/cn/web/wa-bluemix-html5chat/index.html