Socket.io和Phalcon PHP

Socket.io和Phalcon PHP,php,mysql,socket.io,phalcon,Php,Mysql,Socket.io,Phalcon,我正在使用,我想第一次尝试。我用socket.io编写了教程聊天信息。但现在我想在数据库中选择一些数据,用query Phalcon计算表“product”中的行数: $count_products = Product::count(); 例如,在我的HTML页面中,我有5个产品,当我将一个或多个产品添加到我的表产品中时,我希望自动刷新以在我的HTML页面中看到6个产品 你能帮我做这件事吗?一旦你在ajax请求上使用套接字,你应该保持Phalcon不变,并尝试使用+,实现简单的工具 最简单的方

我正在使用,我想第一次尝试。我用socket.io编写了教程聊天信息。但现在我想在数据库中选择一些数据,用query Phalcon计算表“product”中的行数:

$count_products = Product::count();
例如,在我的HTML页面中,我有5个产品,当我将一个或多个产品添加到我的表产品中时,我希望自动刷新以在我的HTML页面中看到6个产品


你能帮我做这件事吗?

一旦你在ajax请求上使用套接字,你应该保持Phalcon不变,并尝试使用+,实现简单的工具

最简单的方法是在节点中创建一个事件转发器,它将侦听一侧的事件,并将它们转发给浏览器用户。更多描述

在您的情况下,我建议向您的Phalcon模型中添加一个
afterSave
侦听器,如中所述。在
afterSave
方法期间,您将能够向您的节点服务传递一个UDP数据包,其中包含
X
表中有新记录的信息

然后,您的节点服务应该将此事件转发到客户端的浏览器,在那里javascript应该决定当前用户是否正在查看
X
表。如果是,它应该锁定视图以防止任何操作,并向Phalcon服务发出ajax请求,该服务应该向DB请求实际数据并刷新视图中的HTML内容

当然,您可以创建一个节点服务,该服务将直接侦听数据库上的更改,并将适当的事件发送给适当的用户,所有内容都准备好进行完全动态更新。但这是一种先进的方法,可能有点过分。我想在这里强调,只要您的Phalcon服务针对速度进行了优化,并且发送的数据不太大,建议的解决方案就可以在几秒钟内工作,给人一种实时的感觉

当然,您可以使用Phalcon而不是Node创建转发服务,但过了一段时间后,您会后悔,因为使用基于事件的工具维护这样一个基于事件的脚本更容易。对于经常使用JavaScript的高级PHP程序员来说,快速学习一点Note.js来制作这样一个简单的解决方案甚至不是一个挑战

用PHP通过socket发送包 我确实在类
Socket
中包含了类似的内容。我更愿意使用持久套接字(
pfsockopen
),因此即使看起来不是这样,也很少有进程会同时使用这个套接字。在
afterSave
中,我正在使用
Send
方法,该方法或多或少执行以下操作:

fwrite($socket, json_encode($msg));
websocket上的Node.js事件转发脚本 示例配置文件
node.json

{
    "wsServer": {
        "listeners": {
            "udp": {
                "port": 8888
            }
        },
        "server": {
            "port": 8000
        }
    }
}
您的依赖项将是
socket.io
dgram
。在学习如何创建节点应用程序之后,您将了解我的意思

为了更容易理解以下内容:

var config = require('node.json').wsServer;
var app = require('http').createServer().listen(config.server.port);
var io = require('socket.io').listen(app);
var listenerDgram = require('dgram').createSocket('udp4');
listenerDgram.bind(config.listeners.udp.port);

var users = {};

io.sockets.on('connection', function(socket) {
    // if you make user to connect by his individual ID during
    // websocket connection, providen after ?, like ?1234
    var user = parseInt(socket.handshake.query.user);

    // here to save user into var users
    if (!users[user]) {
        users[user] = {
            sockets: [socket]
        };
    } else {
        users[user].sockets.push(socket);
    }

    socket.on('disconnect', function() {
        // removing user from var users
        // warning: socket by socket, and if last
        //   socket is closed, remove whole user section
    });

});

// to emit data to all sockets of choosen users
emit = function(sockets, message, data) {
    for (var x in sockets) {
        if (sockets[x]) {
            sockets[x].emit(message, data);
        }
    }
};

// now UDP listening section
listenerDgram.on('message', function(msg, rinfo) {

    // you can declare checkIncoming if you have standarized
    // frames, or just use msg as it is
    var _dat = checkIncoming(msg.toString().trim(), true);
    var _response = {
        action: _dat.action,
        data: _dat.data
    };

    // you can declare standarizeFrame to define your own protocol,
    // or just use _response.
    var frame = standarizeFrame(_response);

    if (_dat.user) { // emitting to single user declared
        emit(users[_dat.user].sockets, 'notification', frame);
    } else { // emitting to all connected users
        io.emit('notification', frame);
    }
});
所以,您将JSONed字符串发送到服务器,节点在端口8888上运行,用户web界面连接到端口8000上的同一主机以接收它们。还有很多调试要做


PS:很抱歉这么武断的回答,但我是自己看的,因为我爱上了Phalcon,对Node.js的存在一无所知。让自己有时间学习Node帮助我将基于事件的解决方案减少到绝对最小,用100行而不是数千行将它们括起来,使它们易于维护,让我的服务器在CPU上深吸一口气,让客户端比基于php的服务器更满意。

这不是答案,但我强烈建议使用为套接字设计的工具,例如特别适合服务实时连接内容的工具。在您的情况下,Phalcon是RESTful API的最佳选择。您的意思是我不应该使用socket.io,但我必须使用Node.js创建套接字,并使用Phalcon服务器端创建web服务?我所有的web服务都将被NodeJSSocket使用?不。一旦您使用socket.io,您就可以将其与node.js一起用作服务器端,它能够连接到db并动态地为您提供所需的数据。你们可以通过举例的方式找到进一步的解释。好的,我明白你们的意思。但我必须保留phalcon服务器端,因为这是一个非常好的php framewor,他很快,我不能完全删除phalcon,因为我的所有项目都是用他构建的。我可以使用phalcon服务器端并在我的视图中实时使用socket io吗?还是两者都用不好?非常感谢你的回答。因此,我将尝试使用afterSave实现您的方法。这似乎是最好的方法,而且比SQL查询上的无限循环要好:)。但是您能告诉我如何从afterSave向节点js发送消息吗?这里有更多信息。希望现在能成功。哇,非常感谢。这真的很好,我会试试的。因此,在代码片段中使用ratchet或elephant.io是没有用的:)
var config = require('node.json').wsServer;
var app = require('http').createServer().listen(config.server.port);
var io = require('socket.io').listen(app);
var listenerDgram = require('dgram').createSocket('udp4');
listenerDgram.bind(config.listeners.udp.port);

var users = {};

io.sockets.on('connection', function(socket) {
    // if you make user to connect by his individual ID during
    // websocket connection, providen after ?, like ?1234
    var user = parseInt(socket.handshake.query.user);

    // here to save user into var users
    if (!users[user]) {
        users[user] = {
            sockets: [socket]
        };
    } else {
        users[user].sockets.push(socket);
    }

    socket.on('disconnect', function() {
        // removing user from var users
        // warning: socket by socket, and if last
        //   socket is closed, remove whole user section
    });

});

// to emit data to all sockets of choosen users
emit = function(sockets, message, data) {
    for (var x in sockets) {
        if (sockets[x]) {
            sockets[x].emit(message, data);
        }
    }
};

// now UDP listening section
listenerDgram.on('message', function(msg, rinfo) {

    // you can declare checkIncoming if you have standarized
    // frames, or just use msg as it is
    var _dat = checkIncoming(msg.toString().trim(), true);
    var _response = {
        action: _dat.action,
        data: _dat.data
    };

    // you can declare standarizeFrame to define your own protocol,
    // or just use _response.
    var frame = standarizeFrame(_response);

    if (_dat.user) { // emitting to single user declared
        emit(users[_dat.user].sockets, 'notification', frame);
    } else { // emitting to all connected users
        io.emit('notification', frame);
    }
});