在这篇文章Redis数据库及其基本操作中介绍了Redis及redis-cli的基本操作. 其中的publish-subscribe机制应用比较广泛, 那么接下来使用nodejs来实现该机制. 本文是对之前的一篇文章使用socket.io+redis来实现基本的聊天室应用场景的详细补充.
关于redis的详细情况, 请参考Redis数据库及其基本操作.
对于redis的前提是redis-server一直在运行, 这里就使用默认的localhost:6379.

node.js连接redis-server

安装redis模块, 该模块会默认安装至当前目录下的node_modules里边:

1
<code class="language-shell hljs cmake">npm install redis</code>

然后连接redis, 并进行get-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>

执行结果:

1
2
3
4
<code class="language-shell hljs avrasm">?  socketio  node redis_node.js
Reply: OK
Reply: testauthor
Reply: world</code>

node.js实现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, 进行比较, 执行结果:

node.js启动一个httpServer

1
2
3
4
5
6
7
8
9
<code class="language-node.js hljs javascript">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/');</code>

执行即可看到:

socket.io在browser与server中同步数据

socket.io连接于browser和nodejs的http服务器之间,可用于二者之间同步数据.
server端: 启动httpserver监听4000端口, 一旦有socket.io的连接建立, 则向socket发送msgReceived消息, 而消息内容是’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 http://127.0.0.1:4000/');
 
var io = require('socket.io')(server);
io.on('connection', function(socket) {
    console.log('connection');
    socket.emit('msgReceived', 'hello');
})</code>

browser端:
建立socket连接, 然后接收socket上的msgReceived消息, 并显示出来.

1
 

<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端改为:

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 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);       
    });
})</code>

首先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机制, 实现的聊天室场景就基本可行了.

使用node.js + socket.io + redis实现基本的聊天室场景的更多相关文章

  1. 转载:node.js socket.io

    本文转自:http://www.xiaocai.name/post/cf1f9_7b6507  学习node.js socket.io 使用 用node.js(socket.io)实现数据实时推送 在 ...

  2. 使用Node.js+Socket.IO搭建WebSocket实时应用

    Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...

  3. (转)使用Node.js+Socket.IO搭建WebSocket实时应用

    Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...

  4. 使用Node.js+Socket.IO搭建WebSocket实时应用【转载】

    原文:http://www.jianshu.com/p/d9b1273a93fd Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新 ...

  5. 基于node.js+socket.io+html5实现的斗地主游戏(1)概述

    一.游戏描述 说是斗地主游戏,其实是寝室自创的"捉双A",跟很多地方的捉红10.打红A差不多,大概规则是: 1.基础牌型和斗地主一样,但没有大小王,共52张牌,每人13张,这也是为 ...

  6. vue.js+socket.io+express+mongodb打造在线聊天

    vue.js+socket.io+express+mongodb打造在线聊天 在线地址观看 http://www.chenleiming.com github地址 https://github.com ...

  7. vue.js+socket.io+express+mongodb打造在线聊天[二]

    vue.js+socket.io+express+mongodb打造在线聊天[二] 在线地址观看 http://www.chenleiming.com github地址 https://github. ...

  8. 玩转Node.js(四)-搭建简单的聊天室

    玩转Node.js(四)-搭建简单的聊天室 Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...

  9. node.js + socket.io实现聊天室一

    前段时间,公司打算在社区做一个聊天室.决定让我来做.本小白第一次做聊天类功能,当时还想着通过ajax请求来实现.经过经理提示,说试试当前流行的node.js 和socket.io来做.于是就上网学习研 ...

随机推荐

  1. Git命令行中文显示错误

    中文文件名乱码(git status.git log.git pull .git push) #不对0x80以上的字符进行quote,解决git status/commit时中文文件名乱码git co ...

  2. Vue.js-----轻量高效的MVVM框架(九、组件利用Props传递数据)

    #使用props传递数据 html:传递普通的字符串 <h3>#使用props传递数据</h3> <div id="dr01"> <div ...

  3. python 操作excel 的包 函数

    ###########sample 1 https://blog.csdn.net/chengxuyuanyonghu/article/details/54951399 python操作excel主要 ...

  4. .NET接收邮件下载邮件附件——openpop.net

    使用OpenPop.Net接收邮件很方便,下面是接收下载邮件附件的代码 OpenPop.Net下载地址 https://sourceforge.net/projects/hpop/ public cl ...

  5. Google Zxing 生成二维码

    Net Zxing 源码地址 http://zxingnet.codeplex.com/ github 地址 https://github.com/zxing/zxing 新建一个Winform 项目 ...

  6. 多线程编程_CountDownLatch

    CountDownLatch是JAVA提供在java.util.concurrent包下的一个辅助类,可以把它看成是一个计数器,其内部维护着一个count计数,只不过对这个计数器的操作都是原子操作,同 ...

  7. PHP速学

    基本代码 <?php echo "Hello world";?> 变量定义 <?php $a=true; $bool_value=true; $integer_v ...

  8. Collections练习之对字符串先折半,再取最长的一个

    不多说,直接上干货! 代码需求 由 [aa, abcde, cba, cba, nbaa, zzz] 变成 max=abcde CollectionsDemo.java package zhouls. ...

  9. 通过一个例子,总结下检测数组属性的N种方法

    判断arr数组里是否含有a,有a返回1;没有返回2var arr = [{a:1,b:2,c:3},{q:1,w:2,e:3},{s:4,g:5,i:9},{b:2,v:3,u:4}]; 检测属性的3 ...

  10. 使用InstallShield打包VS程序

    使用InstallShield打包VS程序 InstallShield是微软自己的一个打包工具,这个打包工具,有其优势也有其弊端.其优势,可以很好且方便地将.NET平台的控件以及程序所需要的dll打包 ...