2016-09-19 50 views
1

我的项目使用Nodejs作为代理服务器与外部API进行通信。了解如何在Node.js和服务器发送事件中使用Redis

API通过Redis发送产品更新(pub/sub);代理服务器处理消息并通过SSE(服务器发送事件)将其发送给客户端。

这是我第一次使用Redis和SSE,在网上寻找教程似乎很容易实现,我做到了。

在客户端上我刚刚创建的EventSource和我收到的更新我用它做什么:

// Client Side 
var source = new EventSource('/redis'); // /redis is path to proxy server 
source.addEventListener('items', handleItemsCallback, false); 
source.addEventListener('users', handleUsersCallback, false); 
source.addEventListener('customers', handleCustomersCallback, false); 

// Function sample... 
function handleItemsCallback (msg) { 
    // Do something with msg... 
} 

在代理服务器上我创建了路由控制器来/redis处理Redis的消息:

exports.redisUpdates = function (req, res) { 
    // Redis Authentication 
    var redisURL = url.parse(process.env.REDISCLOUD_URL); 
    var client = redis.createClient(redisURL.port, redisURL.hostname, {ignore_subscribe_messages: false}); 
    client.auth(redisURL.auth.split(":")[1]); 

    // let request last as long as possible 
    req.socket.setTimeout(0); 

    // Subscribe to channels 
    client.subscribe('items', 'users', 'customers'); 

    // Handle messages 
    client.on('message', function (channel, message) { 
     res.write('retry: 5000\n'); 
     res.write('event: ' + channel + '\n'); 
     res.write('data: ' + message + '\n\n'); 
     res.flush(); // If I do not add this it doesn't push updates to the client (?) 
    }); 

    //send headers for event-stream connection 
    res.writeHead(200, { 
     'Content-Type': 'text/event-stream', 
     'Cache-Control': 'no-cache', 
     'Connection': 'keep-alive' 
    }); 
    res.write('\n'); 

}; 

使用在本地开发环境中它工作正常,但在生产中使用它产生几种不同的错误,应用程序是在托管的HerokuHeroku Metrics显示几个H18,H12,H27错误;

有时/redis呼叫返回状态503;

我想了解的是,如果我正确使用这些服务,为什么所有的教程别提res.flush(),我发现它由我自己来让它工作的第一次...

回答

1

平心而论,由于几个原因,这个问题不是真的可以回答。我不知道你在讨论哪些教程,因为你没有在问题中提及任何问题。我不能代表编写未经引用的教程的人员发言。他们可能只是错了,或者你尝试完成的体系结构在某种程度上有所不同。我也不知道你的项目中使用了什么框架或可选的中间件。

现在,所有这些说有几件事我可以分享,可能会帮助你。

您发现的大多数教程可能无法打开连接并无限期地从流中读取。当进程结束时,http响应会以.end()或类似的方式关闭。由于HTTP响应是写入流,因此它遵循与其他任何流相同的规则。你可以找到很多好的信息关于流在这里:

https://github.com/substack/stream-handbook

重要的东西要明白的是,流可以有一个缓冲和大多数HTTP框架启用压缩这将导致不使用缓冲区。在接下来的环节中的代码示例是一个什么样的框架,愿意为你做幕后一个很好的例子(最小实现当然)

https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#what-we-ve-got-so-far

既然你想输出继续更新,你要么必须等到输出缓冲区大小达到或您必须调用.flush()。

如果您使用express,请查看与压缩中间件相关的下一个Stack Overflow帖子。我相信你必须禁用你的/redis路线。

Node Express Content-Length

我希望帮助一点点。就像我说的那样,很难回答这个问题。 ;)

相关问题