Socket.io from php source

2020-02-01 08:24发布

问题:

I have developed a client-server connection by using socket.io, and i'm happy to say that it works perfectly. The problem comes because I need to create that connection from php Source ( not "echo html javascript" ). Something Like a

$socket = socket.createConectionJS;

I've tried difrerent ways, such as :

  • execute the code from the server ( with spiderMonkey, and node )
  • creating a phpSocket and connecting it to the ServerSocket.j( but obbiously the format is diferent). or ...
  • Finally i've tried by post with curl, where I had access to the serverscript, but i can't open a connection

I'm thinking the only way to resolve it is simulating the web socket connection by creating a socket with the same way as de socket.io class do it but in php

Anny socket.io expert could help ?

Tnks ! ! _

回答1:

Yeah, I had a quick go at it just then. I'm fortunate to have a fairly advanced web scraping library already built in PHP, so I just plugged the XML from TamperData (firefox plugin), into it, and tweaked a few things.

To emulate xhr-polling (my proxy doesn't allow websockets, and this looked simpler anyway)...

Make a request to:

/socket.io/1/?t=1337779479761   

(The 13377... number is just a timestamp, use time() to generate it).

That should return something like this:

682970926640665221:60:60:websocket,htmlfile,xhr-polling,jsonp-polling

Grab the big number at the front out, that's your "[CONNECT_ID]", which you'll keep for the remainder of the session. Now do another request:

/socket.io/1/xhr-polling/[CONNECT_ID]?t=[TIMESTAMP]

And you'll get back something like ::1

That's about as far as I bothered to follow it, it all looked fairly basic from there... no special headers or anything sneaky. Suggest you use TamperData or a packet sniffer, and just follow it yourself. Here was the output from my code:

$ php RealTestCurl.php xml/xhr.xml init1 xhr1 xhr1 xhr1 xhr1

xmlFilename: xml/xhr.xml

Step: init1
Reply: 7638339571841585529:60:60:websocket,htmlfile,xhr-polling,jsonp-polling
Found: connect_id: ([0-9]*) - 7638339571841585529

Step: xhr1
Reply: 1::

Step: xhr1
Reply: ?46?5:::{"name":"news","args":[{"hello":"world"}]}?63?5:::{"name":"this","args":[{"will":"be received by everyone"}]}

Step: xhr1
.... there is a massive 20 second timeout here

Step: xhr1
8::

Step: xhr1
8::

And on the node.js/socket.io side, running on of the basic examples from their front page:

debug - client authorized
info  - handshake authorized 3445861131360107212
debug - setting request GET /socket.io/1/xhr-polling/3445861131360107212?t=1337781185
debug - setting poll timeout
debug - client authorized for 
debug - clearing poll timeout
debug - xhr-polling writing 1::
debug - set close timeout for client 3445861131360107212
debug - websocket writing 5:::{"name":"this","args":[{"will":"be received by everyone"}]}


回答2:

We developed and use in production Elephant.io

We basically use it in our server cron-jobs to notify our front, and in our Symfony2 APIs to push some events to the front.

Have a look, it might help you.

Best



回答3:

I was looking for a really simple way to get PHP to send a socket.io message to clients.

This doesn't require any additional PHP libraries - it just uses sockets.

Instead of trying to connect to the websocket interface like so many other solutions, just connect to the node.js server and use .on('data') to receive the message.

Then, socket.io can forward it along to clients.

I think many of these bloated solutions attempt to get PHP running websocket protocols.

Why bother?

Detect a connection from your PHP server in Node.js like this:

//You might have something like this - just included to show object setup
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

server.on("connection", function(s) {
    var ip = s.remoteAddress;
    if(ip == "::ffff:127.0.0.1") {   //If connection is from our server (localhost)
        s.on('data', function(buf) {
            var js = JSON.parse(buf);
            io.emit(js.msg,js.data); //Send the msg to socket.io clients
        });
    }
});

Here's the incredibly simple php code - I wrapped it in a function - you may come up with something better.

Note that 8080 is the port to my Node.js server - you may want to change.

function sio_message($message, $data) {
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    $result = socket_connect($socket, '127.0.0.1', 8080);
    if(!$result) {
        die('cannot connect '.socket_strerror(socket_last_error()).PHP_EOL);
    }
    $bytes = socket_write($socket, json_encode(Array("msg" => $message, "data" => $data)));
    socket_close($socket);
}

You can use it like this:

sio_message("chat message","Hello from PHP!");

You can also send arrays which are converted to json and passed along to clients.

sio_message("DataUpdate",Array("Data1" => "something", "Data2" => "something else"));

This is a useful way to "trust" that your clients are getting legitimate messages from the server.

You can also have PHP pass along database updates without having hundreds of clients query the database.

I wish I'd found this sooner - hope this helps!