我正在用 NodeJS + Redis + PHP 构建一个 Pub/Sub 服务器,在深入研究这个主题并开始构建一些东西之后,我遇到了一些我在这个过程中看到的困惑。
示例场景:
NodeJs 正确连接到套接字。 警报设置 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() 到 clients 和 4 到 sender 而不是 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/
我想为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
尝试通过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
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我的最终目标是安装当前版本的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
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
有没有办法在这个简单的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
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我有一个存储主机名的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
我想获取模块中定义的所有常量的值: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
我安装了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