How to send messages from php to node.js? I have a linux server running php and node.js.
When a user completes a transaction (via php), I'd like send a message from php to node.js. Node will then update the client via a socket connection.
What's a good way to send a small amount of data from php to node.js without defeating the performance of node.js?
The suggestion seems to be to talk to node through the HTTP interface, just as any other client does. You can talk to node via HTTP using cURL in php
In particular, see this post from Matt Pardee
I faced a similar problem with wanting to keep users informed of a new note added on to a bug, and similar notifications that could really only be effectively sent from PHP to my Node server. What I did follows (apologies if this gets all garbled and unformatted in sending, if it does, I'd be happy to paste the code somewhere else): First, you'll need to use cURL from PHP. I wrote a function for my class like this:
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); }
You'll notice that I send the cURL request on the same server since both PHP and NodeJS are running there, your mileage may vary. The port I set this code to connect to is 8001 (this is the port my Node server is running on, and the port the socket.io server connects to). This sends a HTTP POST request with the post field encoded. This is all pretty standard cURL stuff.
In your Node app you probably have something like:
var server = http.createServer(function(req, res) {}); server.listen(8001); var io = io.listen(server, { transports: ['websocket', 'flashsocket', 'xhr-polling'] }); ...
well what we'll do here is expand on the http.createServer part, to listen for connections coming from our local host ("127.0.0.1"). The createServer code then becomes:
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); }); } } });
From there you can implement your handleServerNotice function..
function handleServerNotice(data) { ... }
etc etc. I haven't tested this in a while, and in fact that code block was commented out on my node server, so I hope what I've pasted here works - in general this concept is proven and I think it'll work for you. Anyway just wanted to be sure you knew it's been a few months so I'm not sure exactly why I commented out. The code I wrote took a little research -- like setting the 'Expect:' header in cURL -- and I was pretty excited when it finally worked. Let me know if you need any additional help.
Best,
Matt Pardee
A bit late, but you could communicate with your node client using the Redis Pub/Sub mechanism in a very simple and effective way. All you need to do is install redis on your server.
On the php side, initialize Redis then publish a message
$purchase_info = json_encode(array('user_id' =>$user_id,
'purchase_information'=>array('item'=>'book','price'=>'2$'));
$this->redis->publish('transaction_completed', $purchase_info);
On the node.js side
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
})
We do it by using message queue. There are a lot of solutions like radis (https://github.com/mranney/node_redis) or 0mq (http://zeromq.org/). It allows to send a message to subscribers (for example from php to nodejs).
Step 1. Get the PHP Emitter: https://github.com/rase-/socket.io-php-emitter
$redis = new \Redis(); // Using the Redis extension provided client
$redis->connect('127.0.0.1', '6379');
$emitter = new SocketIO\Emitter($redis);
$emitter->emit('new question', '<b>h<br/>tml</b>');
add this to your index.js:
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
io.on('connection', function(socket){
socket.on('new question', function(msg) {
io.emit('new question', msg);
});
});
add something like this to your index.html
socket.on('new question', function(msg) {
$('body').append( msg );
});