Javascript 当数据值发生变化时,如何将 redis PUBLISH/SUBSCRIBE 与 nodejs 结合使用来通知客户端?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4441798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:25:57  来源:igfitidea点击:

How to use redis PUBLISH/SUBSCRIBE with nodejs to notify clients when data values change?

javascriptnode.jsredis

提问by u443966

I'm writing an event-driven publish/subscribe application with NodeJS and Redis. I need an example of how to notify web clients when the data values in Redis change.

我正在使用 NodeJS 和 Redis 编写一个事件驱动的发布/订阅应用程序。我需要一个示例,说明如何在 Redis 中的数据值更改时通知 Web 客户端。

回答by Alfred

OLD only use a reference

OLD 仅使用参考

Dependencies

依赖关系

uses express, socket.io, node_redisand last but not least the sample codefrom media fire.

使用expresssocket.ionode_redis以及最后但并非最不重要的来自 media fire的示例代码

Install node.js+npm(as non root)

安装 node.js+npm(作为非 root)

First you should(if you have not done this yet) install node.js+npm in 30 seconds(the right way because you should NOTrun npm as root):

首先,你应该(如果你还没有这样做还)安装的node.js + NPM在30秒(以正确的方式,因为你应该运行NPM作为):

echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
mkdir ~/local
mkdir ~/node-latest-install
cd ~/node-latest-install
curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install # ok, fine, this step probably takes more than 30 seconds...
curl http://npmjs.org/install.sh | sh

Install dependencies

安装依赖

After you installed node+npm you should install dependencies by issuing:

安装 node+npm 后,您应该通过发出以下命令来安装依赖项:

npm install express
npm install socket.io
npm install hiredis redis # hiredis to use c binding for redis => FAST :)

Download sample

下载样本

You can download complete sample from mediafire.

您可以从mediafire下载完整的示例。

Unzip package

解压包

unzip pbsb.zip # can also do via graphical interface if you prefer.

What's inside zip

拉链里面是什么

./app.js

./app.js

const PORT = 3000;
const HOST = 'localhost';

var express = require('express');

var app = module.exports = express.createServer();

app.use(express.staticProvider(__dirname + '/public'));

const redis = require('redis');
const client = redis.createClient();

const io = require('socket.io');

if (!module.parent) {
    app.listen(PORT, HOST);
    console.log("Express server listening on port %d", app.address().port)

    const socket  = io.listen(app);

    socket.on('connection', function(client) {
        const subscribe = redis.createClient();
        subscribe.subscribe('pubsub'); //    listen to messages from channel pubsub

        subscribe.on("message", function(channel, message) {
            client.send(message);
        });

        client.on('message', function(msg) {
        });

        client.on('disconnect', function() {
            subscribe.quit();
        });
    });
}

./public/index.html

./public/index.html

<html>
<head>
    <title>PubSub</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="/javascripts/jquery-1.4.3.min.js"></script>
</head>
<body>
    <div id="content"></div>
    <script>    
        $(document).ready(function() {
            var socket = new io.Socket('localhost', {port: 3000, rememberTransport: false/*, transports: ['xhr-polling']*/});
            var content = $('#content');

            socket.on('connect', function() {
            });

            socket.on('message', function(message){
                content.prepend(message + '<br />');
            }) ;

            socket.on('disconnect', function() {
                console.log('disconnected');
                content.html("<b>Disconnected!</b>");
            });

            socket.connect();
        });
    </script>
</body>
</html>

Start server

启动服务器

cd pbsb    
node app.js

Start browser

启动浏览器

Best if you start google chrome(because of websockets support, but not necessary). Visit http://localhost:3000to see sample(in the beginning you don't see anything but PubSubas title).

如果您启动 google chrome 最好(因为 websockets 支持,但不是必需的)。访问http://localhost:3000以查看示例(一开始你什么也看不到,但PubSub作为标题)。

But on publishto channel pubsubyou should see a message. Below we publish "Hello world!"to the browser.

但是在publish频道上,pubsub您应该会看到一条消息。下面我们发布"Hello world!"到浏览器。

From ./redis-cli

来自 ./redis-cli

publish pubsub "Hello world!"

回答by nak

here's a simplified example without as many dependencies. You do still need to npm install hiredis redis

这是一个没有那么多依赖项的简化示例。你仍然需要npm install hiredis redis

The node JavaScript:

节点 JavaScript:

var redis = require("redis"),
    client = redis.createClient();

client.subscribe("pubsub");
client.on("message", function(channel, message){
  console.log(channel + ": " + message);
});

...put that in a pubsub.js file and run node pubsub.js

...把它放在一个 pubsub.js 文件中并运行 node pubsub.js

in redis-cli:

在 redis-cli 中:

redis> publish pubsub "Hello Wonky!"
(integer) 1

which should display: pubsub: Hello Wonky!in the terminal running node! Congrats!

应该显示:pubsub: Hello Wonky!在终端运行节点!恭喜!

Additional 4/23/2013:I also want to make note that when a client subscribes to a pub/sub channel it goes into subscriber mode and is limited to subscriber commands. You'll just need to create additional instances of redis clients. client1 = redis.createClient(), client2 = redis.createClient()so one can be in subscriber mode and the other can issue regular DB commands.

2013 年 4 月 23 日附加:我还想说明,当客户端订阅发布/订阅频道时,它会进入订阅者模式并且仅限于订阅者命令。您只需要创建额外的 redis 客户端实例。client1 = redis.createClient(), client2 = redis.createClient()所以一个可以处于订阅者模式,另一个可以发出常规的 DB 命令。

回答by nelsonic

CompleteRedis Pub/Sub Example (Real-time Chatusing Hapi.js & Socket.io)

完整的Redis Pub/Sub 示例(使用 Hapi.js 和 Socket.io进行实时聊天

We were trying to understand Redis Publish/Subscribe ("Pub/Sub") and all the existing examples were either outdated, too simple or had no tests. So we wrote a CompleteReal-time Chat using Hapi.js + Socket.io + Redis Pub/Sub Example with End-to-End Tests!

我们试图理解Redis的发布/订阅(“发布/订阅”)和所有现有的例子要么过时,过于简单或没有测试。所以我们使用 Hapi.js + Socket.io + Redis Pub/Sub 示例编写了一个完整的实时聊天和端到端测试

https://github.com/dwyl/hapi-socketio-redis-chat-example

https://github.com/dwyl/hapi-socketio- Redis的聊天,例如

The Pub/Sub component is only a few lines of node.js code: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40

Pub/Sub 组件只有几行 node.js 代码:https: //github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40

Rather than pasting it here (without any context) we encourageyou to checkout/try the example.

我们鼓励您查看/尝试示例,而不是将其粘贴到此处(没有任何上下文)。

We built it using Hapi.jsbut the chat.jsfile is de-coupledfrom Hapi and can easilybe used with a basicnode.js http serveror express(etc.)

我们使用Hapi.js构建它,但该chat.js文件Hapi 分离,可以轻松地与基本的node.js http 服务器express(等)一起使用

回答by Awemo

Handle redis errors to stop nodejs from exiting. You can do this by writing;

处理 redis 错误以阻止 nodejs 退出。你可以通过写作来做到这一点;

subcribe.on("error", function(){
  //Deal with error
})

I think you get the exception because you are using the same client which is subscribed to publish messages. Create a separate client for publishing messages and that could solve your problem.

我认为您会遇到异常,因为您使用的是订阅发布消息的相同客户端。创建一个单独的客户端来发布消息,这可以解决您的问题。

回答by ma11hew28

Check out acani-node on GitHub, especially the file acani-node-server.js. If these links are broken, look for acani-chat-server among acani's GitHub public repositories.

在 GitHub 上查看acani-node,尤其是文件acani-node-server.js。如果这些链接失效,请在acani 的 GitHub 公共存储库中查找 acani-chat-server 。

回答by dirkk0

If you want to get this working with socket.io 0.7 ANDan external webserver you need to change (besides the staticProvider -> static issue):

如果你想让它与 socket.io 0.7外部网络服务器一起工作,你需要改变(除了 staticProvider -> 静态问题):

a) provide the domain nameinstead of localhost (i.e. var socket = io.connect('http://my.domain.com:3000'); ) in the index.html

a)在 index.html 中提供域名而不是 localhost(即 var socket = io.connect('http://my.domain.com:3000'); )

b) change HOST in app.js (i.e. const HOST = 'my.domain.com'; )

b) 更改 app.js 中的 HOST(即 const HOST = 'my.domain.com'; )

c) and add socketsin line 37 of app.js (i.e. 'socket.sockets.on('connection', function(client) { …' )

c) 并在 app.js 的第 37 行添加套接字(即 'socket.sockets.on('connection', function(client) { ...' )

回答by Alex Mikhalev

Update to the code:

更新代码:

staticProvider

静态提供者

now renamed to

现在更名为

static

静止的

see migration guide

请参阅迁移指南

回答by hbinduni

according to @alexsolution. if you have an error like this one as per @tylermention:

根据@alex解决方案。如果根据@tyler提到的类似错误:

node.js:134
        throw e; // process.nextTick error, or 'error'

event on first tick ^ Error: Redis connection to 127.0.0.1:6379 failed - ECONNREFUSED, Connection refused at Socket.

then you need to install Redisfirst. check this out:

那么你需要先安装Redis。看一下这个:

http://redis.io/download

http://redis.io/download