在這篇文章Redis數(shù)據(jù)庫及
其基本操作中介紹了Redis及redis-cli的基本操作. 其中的publish-subscribe機制應(yīng)用比較廣泛,
那么接下來使用nodejs來實現(xiàn)該機制. 本文是對之前的一篇文章使用+redis來實現(xiàn)基本的聊天室應(yīng)用場景的詳細補充.
關(guān)于redis的詳細情況, 請參考Redis數(shù)據(jù)庫及其基本操作.
對于redis的前提是redis-server一直在運行, 這里就使用默認(rèn)的localhost:6379.
node.js連接redis-server
安裝redis模塊, 該模塊會默認(rèn)安裝至當(dāng)前目錄下的node_modules里邊:
1 | <code class = "language-shell hljs cmake" >npm install redis</code>
|
然后連接redis, 并進行g(shù)et-set操作
1 2 3 4 5 6 7 8 | <code class = "language-node.js hljs php" >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);
});</code>
|
執(zhí)行結(jié)果:
1 2 3 4 | <code class = "language-shell hljs avrasm" >? socketio node redis_node.js
Reply: OK
Reply: testauthor
Reply: world</code>
|
node.js實現(xiàn)redis的publish-subscribe
代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <code class = "language-node.js hljs perl" >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);
})</code>
|
另外啟動了一個redis-cli的subscribe, 進行比較, 執(zhí)行結(jié)果:
node.js啟動一個httpServer
1 2 3 4 5 6 7 8 9 | <code class = "language-node.js hljs javascript" >var http = require( 'http' );
http.createServer(function (request, response) {
response.writeHead( 200 , { 'Content-Type' : 'text/plain' });
response.end( 'Hello World\n' );
}).listen( 4000 );
|
執(zhí)行即可看到:
在browser與server中同步數(shù)據(jù)
連接于browser和nodejs的http服務(wù)器之間,可用于二者之間同步數(shù)據(jù).
server端: 啟動httpserver監(jiān)聽4000端口, 一旦有的連接建立, 則向socket發(fā)送msgReceived消息, 而消息內(nèi)容是’hello’.
1 2 3 4 5 6 7 8 9 10 11 12 | <code class = "language-node.js hljs lua" >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 ); var io = require( '' )(server);
io.on( 'connection' , function(socket) {
console.log( 'connection' );
socket.emit( 'msgReceived' , 'hello' );
})</code>
|
browser端:
建立socket連接, 然后接收socket上的msgReceived消息, 并顯示出來.
<script src="https://cdn./-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.on('msgReceived', function(msg) {
alert(msg);
})
</script>
為了方便看到更好的效果, 將兩個browser都打開, 當(dāng)httpserver未啟動時, browser中僅顯示 hello world.
一旦啟動httpserver: node testserver.js, 就可以看到, 兩個browser都會自動彈出alert,
表明接收到了中的消息. 執(zhí)行結(jié)果如下圖:
然后, 停止httpserver, 將發(fā)送msgReceived消息的內(nèi)容更改為’world’, 兩個browser又再次彈出對應(yīng)的alert. 如下圖:
vcr9vt3NrLK9LiDV4sDvvs3KxywgaHR0cHNlcnZlcrfWsfC9q2hlbGxvus13b3JsZLSrtd24+MHLYnJvd3Nlci48L3A+DQo8aDIgaWQ9"
將subscribe的結(jié)果在browser中展示">將subscribe的結(jié)果在browser中展示
接下來要做的是, 通過httpserver訂閱redis的chatchannel頻道, 將該頻道發(fā)布的內(nèi)容更新到browser中.
browser端不變, 而server端改為:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <code class = "language-node.js hljs javascript" >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 ); var io = require( '' )(server);
io.on( 'connection' , function(socket) {
redisclient.on( 'message' , function(error, msg) {
console.log( 'connection' );
console.log(msg);
socket.emit( 'msgReceived' , msg);
});
})</code>
|
首先redisclient訂閱redis-server的chatchannel頻道, 在連接建立時,
監(jiān)聽redisclient的消息, 一旦接收到chatchannel頻道發(fā)布的消息,
立即通過向所有建立連接的browser發(fā)送msgReceived消息, 內(nèi)容是chatchannel頻道的發(fā)布內(nèi)容.
我們這里, 采用redis-cli來發(fā)布消息, 當(dāng)然也可以采用其他方法.
執(zhí)行結(jié)果如下:
首先, redis-cli并未發(fā)布消息
然后, 發(fā)布消息’how are you’, 兩個browser都會收到:
最后, 發(fā)布消息’thank you, goodbye’, 兩個browser都會收到:
至此, 使用node.js和, 結(jié)合redis的publish-subscribe機制, 實現(xiàn)的聊天室場景就基本可行了.