如何从php发送消息到node.js?我有一个运行php和node.js的linux服务器.
当用户完成一个事务(通过php)时,我想从php向node.js发送一条消息.然后,节点将通过套接字连接更新客户端.
在不破坏node.js性能的情况下,从php向node.js发送少量数据的好方法是什么?
Mat*_*sch 24
建议似乎是通过HTTP接口与节点通信,就像任何其他客户端一样.您可以使用php中的cURL通过HTTP与节点通信
请参阅:http://groups.google.com/group/socket_io/browse_thread/thread/74a76896d2b72ccc/216933a076ac2595?pli = 1
特别是,请参阅Matt Pardee的这篇文章
我遇到了类似的问题,希望让用户随时了解添加到bug上的新注释,以及类似的通知,这些通知实际上只能从PHP有效地发送到我的Node服务器.我做了什么(道歉,如果它在发送时出现乱码和未格式化,如果有,我很乐意将代码粘贴到其他地方):首先,你需要使用PHP的cURL.我为我的课写了一个函数,如下所示:
Run Code Online (Sandbox Code Playgroud)function notifyNode($type, $project_id, $from_user, $data) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://127.0.0.1'); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_PORT, 8001); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($ch, CURLOPT_POST, true); $pf = array('f' => $type, 'pid' => $project_id, 'user_from' => $from_user, 'data' => array()); foreach($data as $k => $v) { $pf['data'][$k] = $v; } curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($pf)); curl_exec($ch); curl_close($ch); }您会注意到我在同一台服务器上发送cURL请求,因为PHP和NodeJS都在那里运行,您的里程可能会有所不同.我设置此代码连接的端口是8001(这是我的Node服务器运行的端口,以及socket.io服务器连接的端口).这将发送带有post字段编码的HTTP POST请求.这都是非常标准的cURL内容.
在您的Node应用程序中,您可能具有以下内容:
Run Code Online (Sandbox Code Playgroud)var server = http.createServer(function(req, res) {}); server.listen(8001); var io = io.listen(server, { transports: ['websocket', 'flashsocket', 'xhr-polling'] }); ...那么我们在这里做的是扩展http.createServer部分,以侦听来自我们本地主机("127.0.0.1")的连接.然后createServer代码变为:
Run Code Online (Sandbox Code Playgroud)var server = http.createServer(function(req, res) { // Check for notices from PHP if(res.socket.remoteAddress == '127.0.0.1') { if(req.method == 'POST') { // The server is trying to send us an activity message var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { res.writeHead(200, [[ "Content-Type", "text/plain"] , ["Content-Length", 0] ]); res.write(''); res.end(); //sys.puts(sys.inspect({fields: fields}, true, 4)); handleServerNotice(fields); }); } } });从那里你可以实现你的handleServerNotice函数..
Run Code Online (Sandbox Code Playgroud)function handleServerNotice(data) { ... }我等一段时间没有测试过这个,事实上我的节点服务器上已经注释掉了代码块,所以我希望我在这里粘贴的东西是有效的 - 一般来说这个概念已被证实,我认为它会为你工作.无论如何只是想确定你知道它已经有几个月了所以我不确定为什么我会注释掉它.我编写的代码进行了一些研究 - 比如在cURL中设置'Expect:'标题 - 当它终于奏效时我非常兴奋.如果您需要任何其他帮助,请与我们联系.
最好,
马特帕迪
Rak*_*mer 16
有点晚了,但您可以使用Redis Pub/Sub机制以非常简单有效的方式与您的节点客户端进行通信.您需要做的就是在服务器上安装redis.
在php端,初始化Redis然后发布消息
$purchase_info = json_encode(array('user_id' =>$user_id,
'purchase_information'=>array('item'=>'book','price'=>'2$'));
$this->redis->publish('transaction_completed', $purchase_info);
Run Code Online (Sandbox Code Playgroud)
在node.js端
var redis = require('redis');
var purchase_listener = redis.createClient();
purchase_listener.subscribe('transaction_completed');
purchase_listener.on('message', function(channel, message){
var purchase_data = JSON.parse(message);
user_id = purchase_data.user_id;
purchase_info = purchase_data.purchase_information;
// Process the data
// And send confirmation to your client via a socket connection
})
Run Code Online (Sandbox Code Playgroud)
这可扩展吗?(回应@ mohan-singh)
在讨论可扩展性时,您需要考虑基础架构的体系结构和您的特定需求,但这里有一个快速的答案:我一直在高流量实时应用程序中使用这种机制的变体而没有问题,但这是您应该注意的事项:
Redis PUB/SUB不是一个排队系统,这意味着如果您的节点进程发生故障,那么在它关闭时发送的所有消息都将丢失.
如果你有超过1个发布者的订阅者,他们都将收到相同的消息并处理它,如果你有多个节点进程监听同一个redis数据库处理你的实时逻辑,那就要小心了(有很简单的方法)绕过这个虽然)
这个系统的优点是你不需要在你现有的基础设施上添加任何东西,并且可以立即启动,它非常快,而且它的行为与HTTP服务器完全相同.
以下是更多可扩展选项的替代方案:
这个冗长的编辑的重点是没有神奇的可扩展解决方案,你需要权衡你的选项,看看哪一个最适合你的用例.在我看来,如果你现在开始构建你的第一个迭代,选择你喜欢的任何选项,编写非常干净的代码,当你开始扩展它将很容易改变,这就是我所做的:)
我发现这样的问题可以通过使用 Express 框架来解决。假设 php 向节点服务器发送 json 消息,服务器回复 ok。
在 app.js 中
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var bodyParser = require('body-parser')
app.use(bodyParser.json());
app.post('/phpcallback', function(req, res) {
var content = req.body;
console.log('message received from php: ' + content.msg);
//to-do: forward the message to the connected nodes.
res.end('ok');
});
http.listen(8080, function(){
var addr = http.address();
console.log('app listening on ' + addr.address + ':' + addr.port);
});
Run Code Online (Sandbox Code Playgroud)
在 test.php 中
<?php
$data = array("name" => "Robot", "msg" => "Hi guys, I'm a PHP bot !");
$data_string = json_encode($data);
$ch = curl_init('http://localhost:8080/phpcallback');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
echo curl_exec($ch)."\n";
curl_close($ch);
?>
Run Code Online (Sandbox Code Playgroud)
这里我们还有一个更详细的示例,其中 php 脚本可以向特定聊天室的用户发送消息。
我对 Redis 方法的个人印象:繁琐。您需要同时运行 Apache、nodeJS 和 Redis,三台服务器。而且PubSub机制和socket.io的emit大不相同,所以你需要看看它是否与你现有的代码兼容。
| 归档时间: |
|
| 查看次数: |
19531 次 |
| 最近记录: |