Communicating With Node Server Using PHP

9,706 views
Skip to first unread message

Montoyland

unread,
Jan 22, 2011, 4:07:53 PM1/22/11
to Socket.IO
I'm designing a collaborative working environment using Node.js and
Socket.IO - a certain module uses Flash as a front-end to edit a
document. This module sends a byteArray to a PHP routine that then
creates a thumbnail preview of the edited document. Ideally, I would
like to send a message to the Node server that a new thumbnail has
been created so that all clients may refresh their "gallery" view.
Since the jpg writing call is handled by PHP, I would like to do this
within this same script - is there a way to simply send a message (an
event trigger, really) to Node.js via PHP? Everything I've tried comes
up short, but then again, I'm a Node noob - any advice is greatly
appreciated! I don't really need to handle a response - the window
that launched the Flash editor has an open connection to Node.js with
Socket.IO, so it simply needs to receive a rendered image broadcast
from the server triggered by the PHP script. Thanks in advance!

Matt Pardee

unread,
Jan 22, 2011, 4:35:59 PM1/22/11
to sock...@googlegroups.com
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

Matt Pardee

unread,
Jan 22, 2011, 4:40:35 PM1/22/11
to Socket.IO
Oh I did forget about at least one dependency -- formidable. That's
here:

https://github.com/felixge/node-formidable

and I included it like this:

formidable = require('../lib/formidable')

Best,

M

Montoyland

unread,
Jan 22, 2011, 5:54:52 PM1/22/11
to Socket.IO
Thanks Matt, this makes perfect sense. I'll give it a try and post
back with results (no pun intended). I actually had the cURL part
figured out, but didn't quite know how to handle the request on the
Node server. Thanks for generously sharing your code!
For those with similar issue: This post also looks promising:
http://www.toxiccoma.com/random/nodejs-0195-http-post-handling-of-form-data

Montoyland

unread,
Jan 22, 2011, 11:29:45 PM1/22/11
to Socket.IO
After trying to implement your code, it's still not clear to me how I
can gain access to all connected clients established via the Socket.IO
instance in order to broadcast a message. It would seem that the
server must first be defined in order to create the socket instance.
Since I need the server to define and handle the inbound PHP HTTP POST
request - how do I use this request to notify connected clients on
the socket if the socket hasn't yet been defined at this point? It's a
chicken and egg problem...

I'm wondering if maybe I shouldn't use a PHP TCP connection to
communicate with the Node server - this way all communication would be
established through sockets thereby bypassing the chicken and egg
problem above. PHP would use the fsock_open function to establish the
communication and send the write notification to the server, which
would then get broadcast to all connected clients...

Does this approach hold water?

On Jan 22, 5:54 pm, Montoyland <montoyl...@gmail.com> wrote:
> Thanks Matt, this makes perfect sense. I'll give it a try and post
> back with results (no pun intended). I actually had the cURL part
> figured out, but didn't quite know how to handle the request on the
> Node server. Thanks for generously sharing your code!
> For those with similar issue: This post also looks promising:http://www.toxiccoma.com/random/nodejs-0195-http-post-handling-of-for...

Montoyland

unread,
Jan 23, 2011, 1:23:21 AM1/23/11
to Socket.IO
After reframing my specific problem, I realized that I may have been
over-thinking it: while I am still curious as to how to achieve what
I'm after using PHP, it's clear that the simplest solution is for the
PHP script to simply pass a string back to the Flash movie signaling
success or failure following the write operation, and based on this
result, have Flash call a JavaScript function on the page that embeds
it that would set up the connection and refresh request to the Node
server using Socket.IO. This is simpler and perhaps more elegant since
we keep all server calls in the same preferred language.

On Jan 22, 11:29 pm, Montoyland <montoyl...@gmail.com> wrote:
> After trying to implement your code, it's still nubot clear to me how I

Ginko

unread,
Mar 10, 2012, 4:20:00 PM3/10/12
to sock...@googlegroups.com
The io object is available ( even if it's initialized later, it will not be called before it's actually initialized ), and so, you can send messages to a group of socket using the room system ( with io.sockets.in('room_name').emits('event', data); ).

If you want to send a message to an unique socket, you'll have to join every socket in an individual room ( using it's id as room name for exemple ).

I'm using this on a chat server and it's working very well.
Reply all
Reply to author
Forward
0 new messages