草庐IT

node.js - Node + Redis + PHP 获取实时问题

coder 2023-11-08 原文

我正在用 NodeJS + Redis + PHP 构建一个 Pub/Sub 服务器,在深入研究这个主题并开始构建一些东西之后,我遇到了一些我在这个过程中看到的困惑。

示例场景:

  • 5 用户通过 NodeJs 正确连接到套接字。
  • 其中一个点击按钮向除他以外的所有连接用户发送自定义警报
  • Php 通过调用 ajax 接收警报消息(作为示例)
  • PHP 发布回 Redis
  • Redis收到事件并触发socket.io广播事件

设置 View :

<input type="text" id="message">
<button id="sendMessage">Send alert</button>

客户端Js

var socket = io.connect('http://127.0.0.1:3000/');

socket.on('notification', function (data) {

    alert(data.message);
    console.log('message received');
});

// Ajax event
$(document).on('click','#sendMessage', function(){

    $.ajax({
      url: '/send/notification',
      method: 'POST',
      type: 'JSON',
      data: { message: $('#message').val() },
      success:function(data)
      {
        console.log('message sent');
      }
    })
});

用于与 redis 通信的 Php 服务器端

$message = $_POST['message'];
$redis = new Predis\Client();
$redis->publish('notification',$message);

NodeJs

此时,在我的 NodeJs 服务器上,我将去监听 Redis 中的 message 事件,然后将事件广播到套接字,但这是我遇到的第一个问题.

var http = require('http');
var app  = http.createServer();
var io   = require('socket.io')(app);
var redis = require('redis');

app.listen(3000,'127.0.0.1',function(){
    console.log("listening:", app.address().port, app.address().address);
});

io.on('connection', function(client){
    var redisClient = redis.createClient();

    redisClient.subscribe('notification');

    redisClient.on("message",function(channel,data){

          // This line should broadcast to all the client except the sender
          socket.broadcast.emit(channel,JSON.parse(data));

          console.log(channel);
    });
});

问题

此时我在 console.log() channel 我可以在我的终端上看到 5 个日志“通知” 为什么是 5?

当 socket.io 广播事件时,它会执行 5 次,在这种情况下发送 5 alert()clients4sender 而不是 1 代表所有客户端 0 代表发件人。

时间取决于连接的用户数量我真的不明白我错过了什么,因为这不应该是正确的行为。

我已经尝试将 redisClient 的创建和 channel 订阅放在 io.on('connection') 之外,但没有成功,结果相同.


另一个测试

如果我像这样在套接字连接上广播事件:

io.on('connection', function(client)
{
     client.broadcast.emit('notification','hello');
});

它工作正常,所以我认为是 redis 的问题。任何建议将不胜感激。

最佳答案

您连接了 5 个客户端,因此“连接”事件被触发了 5 次。 因此,redis 有 5 个监听器,然后全部广播。

正确的做法有两种:

a) 每个连接1个监听器,只向连接发送消息

io.on('connection', function(socket){
    var redisClient = redis.createClient();

    redisClient.subscribe('notification');

    redisClient.on("message",function(channel,data){

          // This line should broadcast to only the current connection
          socket.emit(channel,JSON.parse(data));

          console.log(channel);
    });
});

b) 1个全局监听器,广播给所有客户端

var redisClient = redis.createClient();

redisClient.subscribe('notification');

redisClient.on("message",function(channel,data){

   // This line should broadcast to all the client except the sender
   io.sockets.emit(channel,JSON.parse(data));

   console.log(channel);
});

我更喜欢方法 b),因为它只需要一个 Redis 连接。

关于node.js - Node + Redis + PHP 获取实时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26350178/

有关node.js - Node + Redis + PHP 获取实时问题的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  5. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  6. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  7. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  8. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  9. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  10. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

随机推荐