使用node.js + socket.io + redis實現基本的聊天室情境
在這篇文章Redis資料庫及其基本操作中介紹了Redis及redis-cli的基本操作. 其中的publish-subscribe機制應用比較廣泛, 那麼接下來使用nodejs來實現該機制. 本文是對之前的一篇文章使用socket.io+redis來實現基本的聊天室應用情境的詳細補充.
關於redis的詳細情況, 請參考Redis資料庫及其基本操作.
對於redis的前提是redis-server一直在運行, 這裡就使用預設的localhost:6379.
node.js串連redis-server
安裝redis模組, 該模組會預設安裝至目前的目錄下的node_modules裡邊:
npm install redis
然後串連redis, 並進行get-set操作
var redis = require('redis');var redisclient = redis.createClient();redisclient.on('connect',function(){ redisclient.set('author', 'testauthor', redis.print); redisclient.get('author', redis.print); redisclient.get('hello', redis.print);});
執行結果:
? socketio node redis_node.jsReply: OKReply: testauthorReply: world
node.js實現redis的publish-subscribe
代碼如下:
var redis = require('redis');var redisclient = redis.createClient();var sub = function(c) { var c = c || 'chatchannel'; redisclient.subscribe(c, function(e) { console.log('subscribe channel : ' + c); });}sub();redisclient.on('message', function(error, response) { console.log(response);})
另外啟動了一個redis-cli的subscribe, 進行比較, 執行結果:
node.js啟動一個httpServer
var http = require('http');// var server = http.createServer().listen(4000);http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(4000);console.log('Server running at http://127.0.0.1:4000/');
執行即可看到:
socket.io在browser與server中同步資料
socket.io串連於browser和nodejs的http伺服器之間,可用於二者之間同步資料.
server端: 啟動httpserver監聽4000連接埠, 一旦有socket.io的串連建立, 則向socket發送msgReceived訊息, 而訊息內容是’hello’.
var server = require('http').createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(4000);console.log('Server running at http://127.0.0.1:4000/');var io = require('socket.io')(server);io.on('connection', function(socket) { console.log('connection'); socket.emit('msgReceived', 'hello');})
browser端:
建立socket串連, 然後接收socket上的msgReceived訊息, 並顯示出來.
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>hello world <script type="text/javascript"> console.log("hello"); var socket = io('http://localhost:4000'); socket.on('connection', function() { console.log('connection setup for socket.io') }); socket.on('msgReceived', function(msg) { alert(msg); })</script>
為了方便看到更好的效果, 將兩個browser都開啟, 當httpserver未啟動時, browser中僅顯示 hello world. 一旦啟動httpserver: node testserver.js, 就可以看到, 兩個browser都會自動彈出alert, 表明接收到了socket.io中的訊息. 執行結果如:
然後, 停止httpserver, 將發送msgReceived訊息的內容更改為’world’, 兩個browser又再次彈出對應的alert. 如:
vcr9vt3NrLK9LiDV4sDvvs3KxywgaHR0cHNlcnZlcrfWsfC9q2hlbGxvus13b3JsZLSrtd24+MHLYnJvd3Nlci48L3A+DQo8aDIgaWQ9"將subscribe的結果在browser中展示">將subscribe的結果在browser中展示
接下來要做的是, 通過httpserver訂閱redis的chatchannel頻道, 將該頻道發布的內容更新到browser中.
browser端不變, 而server端改為:
var server = require('http').createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(4000);var redis = require('redis');var redisclient = redis.createClient();var sub = function(c) { var c = c || 'chatchannel'; redisclient.subscribe(c, function(e) { console.log('subscribe channel : ' + c); });}sub();console.log('Server running at http://127.0.0.1:4000/');var io = require('socket.io')(server);io.on('connection', function(socket) { redisclient.on('message', function(error, msg) { console.log('connection'); console.log(msg); socket.emit('msgReceived', msg); });})
首先redisclient訂閱redis-server的chatchannel頻道, 在socket.io串連建立時, 監聽redisclient的訊息, 一旦接收到chatchannel頻道發布的訊息, 立即通過socket.io向所有建立串連的browser發送msgReceived訊息, 內容是chatchannel頻道的發布內容. 我們這裡, 採用redis-cli來發布訊息, 當然也可以採用其他方法.
執行結果如下:
首先, redis-cli並未發布訊息
然後, 發布訊息’how are you’, 兩個browser都會收到:
最後, 發布訊息’thank you, goodbye’, 兩個browser都會收到:
至此, 使用node.js和socket.io, 結合redis的publish-subscribe機制, 實現的聊天室情境就基本可行了.