在这篇文章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. Zero Sum Subarray

    Given an integer array, find a subarray where the sum of numbers is zero. Your code should return th ...

  2. oracle db 产品路线图

    Release Schedule of Current Database Releases (文档 ID 742060.1)

  3. python—datetime time 模板学习

    写在前面:本人在学习此内容是通过 https://www.cnblogs.com/pycode/p/date.html 文章学习! 时间模块——time python 中时间表示方法有:时间戳_:格式 ...

  4. Mybatis学习笔记5 - 参数处理

    1.单个参数:mybatis不会做特殊处理,#{参数名}:取出参数值. 2.多个参数:mybatis会做特殊处理. 多个参数会被封装成 一个map, key:param1...paramN,或者参数的 ...

  5. [转]如何在.NET MVC中使用jQuery并返回JSON数据

    本文转自:http://blog.sina.com.cn/s/blog_48e42dc90100xp1p.html 二.开始实践 - jQuery端 假设我们要从服务器端获取一个文章列表,并把文章条目 ...

  6. (转)DNS解析过程详解

    DNS解析过程详解 原文:http://blog.csdn.net/crazw/article/details/8986504 先说一下DNS的几个基本概念: 一. 根域 就是所谓的“.”,其实我们的 ...

  7. C#:新邮件监听及搜索

    在项目中,我们需要监听邮件服务器,看是否有新的邮件进入.下面的代码可以帮助我们监听新邮件,并对已有的邮件进行查找: using System; using System.Collections.Gen ...

  8. 亲测SQLServer的最大连接数

    很多做架构设计.程序开发.运维.技术管理的朋友可能或多或少有这样的困惑: SQLServer到底支持多少连接数的并发? SQLServer是否可以满足现有的应用吗? 现有的技术架构支持多少连接数的并发 ...

  9. java实现新旧版本号比较

    项目中需要使用比较现在线上版本和新版本,然后新版本执行新方法,方法如下: /** * * @方法名称:comparaVersion * @内容摘要: <版本比较> * @param old ...

  10. C++ VS编译问题--LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    用VS编译时,当出现错误LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏: 这个问题的解决方案为: 1. 找到项目\xx属性\配置属性\清单工具\输 ...