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

发布于 2024-12-06 19:25:05 字数 1003 浏览 1 评论 0原文

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

我的理想场景: 我想使用 Socket.IO 向已连接的用户发布实时推文以及其他信息的实时更新。

如果我可以做一些像 HTTP POST(从任何后端)一样简单的事情来向所有连接的客户端广播信息,那就太好了。

我的问题: Socket.IO 客户端实现非常简单……我可以处理。但我不知道我要求的功能是否已经存在......如果不存在,实现它的最佳方法是什么?

[更新]

我的解决方案:我创建了一个名为 Pega.IO 的项目,它可以满足我的需求。基本上,它允许您照常使用 Socket.IO (0.8+),但您可以使用 HTTP POST 向连接的用户发送消息。

它使用带有 Redis 后端的 Express Web 服务器。从理论上讲,这应该非常容易扩展——我将继续为这个项目做出贡献。

Pega.IO - github

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

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

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

启动并运行后,只需:

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

,数据如下所示:

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

这就是全部到它。从任何后端到 Pega.IO 服务器的 HTTP POST。

My Setup:
I have an existing python script that is using Tweepy to access the Twitter Streaming API. I also have a website that shows aggregate real-time information from other sources from various back-ends.

My Ideal Scenario:
I want to publish real-time tweets as well as real-time updates of my other information to my connected users using Socket.IO.

It would be really nice if I could do something as simple as an HTTP POST (from any back-end) to broadcast information to all the connected clients.

My Problem:
The Socket.IO client implementation is super straight forward... i can handle that. But I can't figure out if the functionality I'm asking for already exists... and if not, what would be the best way to make it happen?

[UPDATE]

My Solution: I created a project called Pega.IO that does what I was looking for. Basically, it lets you use Socket.IO (0.8+) as usual, but you can use HTTP POST to send messages to connected users.

It uses the Express web server with a Redis back-end. Theoretically this should be pretty simple to scale -- I will continue contributing to this project going forward.

Pega.IO - github

To install on Ubuntu, you just run this command:

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

This will create a Pega.IO server that is listening on port 8888.

Once you are up and running, just:

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

with data that looks like this:

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

That's all there is to it. HTTP POST from any back-end to your Pega.IO server.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

洒一地阳光 2024-12-13 19:25:05

我发现处理此类事情的最佳方法是使用消息代理。就我个人而言,我为此使用了 RabbitMQ,它似乎满足您在其他答案的评论中提到的要求(socket.io 0.7 和可扩展)。如果您使用 RabbitMQ,我建议使用适用于 Node 的 amqp 模块(可通过 npm 获取)和适用于 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);
    }

编辑:上面的示例使用不持久消息的扇出交换。扇出交换可能是您的最佳选择,因为可扩展性是一个问题(即:您正在运行多个运行客户端可以连接到的节点的机器)。

The best way I've found for this sort of thing is using a message broker. Personally, I've used RabbitMQ for this, which seems to meet the requirements mentioned in your comment on the other answer (socket.io 0.7 and scalable). If you use RabbitMQ, I'd recommend the amqp module for node, available through npm, and the Pika module for Python.

An example connector for Python using pika. This example accepts a single json-serialized argument:

    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()

Very basic connection code on the node end might look like this:

    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);
    }

Edit: The example above uses a fan-out exchange that does not persist messages. Fan-out exchange is likely going to be your best option since scalability is a concern (ie: you are running more than one box running Node that clients can be connected to).

女中豪杰 2024-12-13 19:25:05

为什么不编写您的 Node 应用程序,使其包含两部分:

  1. Socket.IO 部分,直接与客户端通信,以及
  2. 某种 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 等框架或许多其他框架之一来解析 POST 请求的正文并提取所需的数据)。

Why not write your Node app so that there are two parts:

  1. The Socket.IO portion, which communicates directly with the clients, and
  2. An HTTP API of some sort, which receives POST requests and then broadcasts appropriate messages with Socket.IO.

In this way, your application becomes a "bridge" between your non-Node apps and your users' browsers. The key here is to use Socket.IO for what it was made for--real time communication to browsers--and rely on other Node technologies for other parts of your application.

[Update]

I'm not on a development environment at the moment, so I can't get you a working example, but some pseudocode would look something like this:

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);

With this, you'd have a web server on port 8080 that you can use to listen to web requests (you could use a framework such as Express or one of many others to parse the body of the POST request and extract the data you need).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文