Socket.io 和 Phalcon PHP
Socket.io and Phalcon PHP
我是第一次使用 Phalcon PHP and I want to try socket.io。我用 socket.io 做了教程聊天消息。但是现在我想 select 我的数据库中的一些数据来计算 table 'product' 中的行数与查询 Phalcon :
$count_products = Product::count();
例如,在我的 HTML 页面中,我有 5 种产品,当我将一种或多种产品添加到我的 table 产品中时,我希望自动刷新以在我的 [=] 中看到 6 种产品22=]页。
你能帮我做吗?
一旦你在 ajax 请求上使用套接字,你应该保持你的 Phalcon 不变,并尝试使用 node.js+socket.io.
实现简单的工具
最简单的方法是在 Node 中创建一个事件转发器,它会在一侧监听事件,并将它们转发给用户浏览器。更多描述 .
对于您的情况,我建议向您的 Phalcon 模型添加一个 afterSave
侦听器,如 documentation 中所述。在 afterSave
方法期间,您将能够通过例如。一个 UDP 数据包到您的节点服务,其中包含 X
table.
中有新记录的信息
如果当前用户正在查看 X
table,那么您的节点服务应该将此事件转发到客户端的浏览器,javascript 应该决定。如果是,它应该锁定视图以防止任何操作并启动对 Phalcon 服务的 ajax 请求,它应该向您的数据库询问实际数据并刷新视图中的 HTML 内容。
当然,您可以制作一个节点服务,该服务将直接在数据库上侦听更改,并将适当的事件发送给适当的用户,所有内容都准备好完全动态更新。但这是一种高级方法,可能有点矫枉过正。我想在这里强调一下,只要您的 Phalcon 服务针对速度进行了优化并且发送的数据不是太大,建议的解决方案确实可以在几分之一秒内完成,给人一种实时的感觉。
当然,您可以使用 Phalcon 而不是 Node 创建您的转发服务,但时间一长您就会后悔,因为实际上使用基于事件的工具来维护这样一个基于事件的脚本会更容易。同样对于不时使用 JavaScript 的高级 PHP 程序员来说,快速学习这么少的 Note.js 来制作如此简单的解决方案甚至不是挑战。
使用 PHP
通过套接字发送包
$host = array(
'scheme' => 'udp', // udp makes it lightweight and connectionless
'host' => '192.168.10.10' // choose an IP where node is running
'port' => '8888' // choose one > 1023
);
$param = sprintf('%s://%s:%s', $host['scheme'], $host['host'], $host['port']);
$socket = fsockopen($param, $errno, $errstr, $timeout);
我在 class Socket
中确实有类似的东西。我宁愿使用持久套接字 (pfsockopen
),因此很少有进程一次会使用这个套接字,即使它看起来不是这样。在 afterSave
中,我正在使用 Send
方法,它或多或少做了:
fwrite($socket, json_encode($msg));
Node.js 基于 websocket 的事件转发脚本
示例配置文件node.json
:
{
"wsServer": {
"listeners": {
"udp": {
"port": 8888
}
},
"server": {
"port": 8000
}
}
}
您的依赖项将是 socket.io
和 dgram
。一旦您学会了如何创建 Node 应用程序,您稍后就会明白我的意思。
为了更容易理解以下内容:
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 PHP and I want to try socket.io。我用 socket.io 做了教程聊天消息。但是现在我想 select 我的数据库中的一些数据来计算 table 'product' 中的行数与查询 Phalcon :
$count_products = Product::count();
例如,在我的 HTML 页面中,我有 5 种产品,当我将一种或多种产品添加到我的 table 产品中时,我希望自动刷新以在我的 [=] 中看到 6 种产品22=]页。
你能帮我做吗?
一旦你在 ajax 请求上使用套接字,你应该保持你的 Phalcon 不变,并尝试使用 node.js+socket.io.
实现简单的工具最简单的方法是在 Node 中创建一个事件转发器,它会在一侧监听事件,并将它们转发给用户浏览器。更多描述
对于您的情况,我建议向您的 Phalcon 模型添加一个 afterSave
侦听器,如 documentation 中所述。在 afterSave
方法期间,您将能够通过例如。一个 UDP 数据包到您的节点服务,其中包含 X
table.
如果当前用户正在查看 X
table,那么您的节点服务应该将此事件转发到客户端的浏览器,javascript 应该决定。如果是,它应该锁定视图以防止任何操作并启动对 Phalcon 服务的 ajax 请求,它应该向您的数据库询问实际数据并刷新视图中的 HTML 内容。
当然,您可以制作一个节点服务,该服务将直接在数据库上侦听更改,并将适当的事件发送给适当的用户,所有内容都准备好完全动态更新。但这是一种高级方法,可能有点矫枉过正。我想在这里强调一下,只要您的 Phalcon 服务针对速度进行了优化并且发送的数据不是太大,建议的解决方案确实可以在几分之一秒内完成,给人一种实时的感觉。
当然,您可以使用 Phalcon 而不是 Node 创建您的转发服务,但时间一长您就会后悔,因为实际上使用基于事件的工具来维护这样一个基于事件的脚本会更容易。同样对于不时使用 JavaScript 的高级 PHP 程序员来说,快速学习这么少的 Note.js 来制作如此简单的解决方案甚至不是挑战。
使用 PHP
通过套接字发送包$host = array(
'scheme' => 'udp', // udp makes it lightweight and connectionless
'host' => '192.168.10.10' // choose an IP where node is running
'port' => '8888' // choose one > 1023
);
$param = sprintf('%s://%s:%s', $host['scheme'], $host['host'], $host['port']);
$socket = fsockopen($param, $errno, $errstr, $timeout);
我在 class Socket
中确实有类似的东西。我宁愿使用持久套接字 (pfsockopen
),因此很少有进程一次会使用这个套接字,即使它看起来不是这样。在 afterSave
中,我正在使用 Send
方法,它或多或少做了:
fwrite($socket, json_encode($msg));
Node.js 基于 websocket 的事件转发脚本
示例配置文件node.json
:
{
"wsServer": {
"listeners": {
"udp": {
"port": 8888
}
},
"server": {
"port": 8000
}
}
}
您的依赖项将是 socket.io
和 dgram
。一旦您学会了如何创建 Node 应用程序,您稍后就会明白我的意思。
为了更容易理解以下内容:
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基础的。