从各种后端向Socket.IO客户端发送消息的最佳方式是什么?

我的设置:我有一个使用Tweepy访问Twitter Streaming API的现有Python脚本。 我也有一个网站,显示来自各种后端的其他来源的汇总实时信息。

我的理想情景:我想发布实时tweets以及实时更新我的​​其他信息给我的连接用户使用Socket.IO。

如果我可以像HTTP POST(从任何后端)那样简单地向所有连接的客户端广播信息,这将是非常好的。

我的问题:Socket.IO客户端实现是非常直接的…我可以处理。 但是我不知道我要求的function是否已经存在…如果没有,那么最好的方法是什么?

[UPDATE]

我的解决scheme:我创build了一个名为Pega.IO的项目,它可以满足我的要求。 基本上,它可以让你像往常一样使用Socket.IO(0.8+),但你可以使用HTTP POST发送消息给连接的用户。

它使用Express Web服务器和Redis后端。 从理论上讲,这应该是非常简单的 – 我将继续为这个项目做出贡献。

Pega.IO – github

要在Ubuntu上安装,只需运行以下命令:

curl http://cloud.github.com/downloads/Gootch/pega.io/install.sh | sh 

这将创build一个正在侦听端口8888的Pega.IO服务器。

一旦你开始运行,只需:

HTTP POST http://your-server:8888/send

数据看起来像这样:

 channel=whatever&secretkey=mysecret&message=hello+everyone 

这里的所有都是它的。 从任何后端HTTP POST到您的Pega.IO服务器。

我发现这种事情的最好方法是使用消息代理。 就我个人而言,我已经使用了RabbitMQ,这似乎满足您在其他答案(socket.io 0.7和可伸缩)的评论中提到的要求。 如果你使用RabbitMQ,我推荐使用npm的amqp模块和Python的Pika模块。

使用pika的Python示例连接器。 这个例子接受一个单一的json序列化的参数:

  def amqp_transmit(message): connection = pika.AsyncoreConnection(pika.ConnectionParameters(host=settings.AMQP_SETTINGS['host'], port=settings.AMQP_SETTINGS['port'], credentials=pika.PlainCredentials(settings.AMQP_SETTINGS['username'], settings.AMQP_SETTINGS['pass']))) channel = connection.channel() channel.exchange_declare(exchange=exchange_name, type='fanout') channel.queue_declare(queue=NODE_CHANNEL, auto_delete=True, durable=False, exclusive=False) channel.basic_publish(exchange=exchange_name, routing_key='', body=message, properties=pika.BasicProperties( content_type='application/json'), ) print ' [%s] Sent %r' %(exchange_name, message) connection.close() 

节点端的非常基本的连接代码可能如下所示:

  var connection = amqp.createConnection( {host: amqpHost, port: amqpPort, password: amqpPass}); function setupAmqpListeners() { connection.addListener('ready', amqpReady) connection.addListener('close', function() { console.log('Uh oh! AMQP connection failed!'); }); connection.addListener('error', function(e) {throw e}); } function amqpReady(){ console.log('Amqp Connection Ready'); var q, exc; q = connection.queue(queueName, {autoDelete: true, durable: false, exclusive: false}, function(){ console.log('Amqp Connection Established.'); console.log('Attempting to get an exchange named: '+exchangeName); exc = connection.exchange(exchangeName, {type: 'fanout', autoDelete: false}, function(exchange) { console.log('Amqp Exchange Found. ['+exchange.name+']'); q.bind(exc, '#'); console.log('Amqp now totally ready.'); q.subscribe(routeAmqp); } ); } ); } routeAmqp = function(msg) { console.log(msg); doStuff(msg); } 

编辑:上面的例子使用扇出交换,不坚持消息。 扇出交换很可能是你最好的select,因为可伸缩性是一个问题(即:你正在运行多个运行Node的客户端可以连接到的盒子)。

为什么不写你的Node应用程序,以便有两个部分:

  1. Socket.IO部分,直接与客户端通信
  2. 某种types的HTTP API,它接收POST请求,然后用Socket.IO广播适当的消息。

通过这种方式,您的应用程序将成为您的非Node应用程序与用户浏览器之间的“桥梁”。 这里的关键是使用Socket.IO实现与浏览器的实时通信,并将其他Node技术用于应用程序的其他部分。

[更新]

我目前还没有开发环境,所以我不能给你一个工作的例子,但是一些伪代码看起来像这样:

 http = require('http'); io = require('socket.io'); server = http.createServer(function(request, response) { // Parse the HTTP request to get the data you want io.sockets.emit("data", whatever); // broadcast the data to Socket.IO clients }); server.listen(8080); socket_server = io.listen(server); 

有了这个,你可以在端口8080上安装一个web服务器,你可以使用这个服务器来监听web请求(你可以使用Express等框架来parsingPOST请求的主体并提取你需要的数据)。