1

I got a connection between PHP and Node using Redis working fine, but I'm intrigued by doing it without any external libraries and services and just with sockets.

I'm not sure on how much performance will suffer without having Redis in the middle, but for simpler projects, this would be nice with lesser code.

I got most of the code from this answer in Using PHP with Socket.io but I had to change some of the vars. But it's not working as expected.

I tried both with and without https, since I will be using https, but I tried making a simpler example with http just to get it working.

  • send.php creates and writes to a socket. I can confirm that it connects to node, since I get an error if node isn't running.
  • socket.js doesn't return anything in the console.logs.
  • socket-https.js returns connection from ::ffff:127.0.0.1 but isn't reading the socket.on('data'). What did I miss?

I think I misunderstand something in the var/require section in the http-version.

Can anyone spot why it's not working?

socket.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

var listener = app.listen(8080, function(){
    console.log('Listening on port ' + listener.address().port); 
});

http.on("connection", function(socket) {
    console.log("connection");
    if(socket.remoteAddress == "::ffff:127.0.0.1") {
        console.log("connection from " + socket.remoteAddress);
        socket.on('data', function(buf) {
            var js = JSON.parse(buf);
            console.log("on data: " + js); // Not working
        });
    }
});

socket-https.js

var fs = require('fs');
var privateKey  = fs.readFileSync('my-domain-com.key', 'utf8');
var certificate = fs.readFileSync('my-domain-com.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var app = require('express')();
var https = require('https').createServer(credentials, app);
var io = require('socket.io')(https);

https.listen(8080, function(){
  console.log('Server online');
});

https.on("connection", function(socket) {
    console.log("connection"); // Works!
    if(socket.remoteAddress == "::ffff:127.0.0.1") {
        console.log("connection from " + socket.remoteAddress); // Works!
        socket.on('data', function(buf) {
            var js = JSON.parse(buf);
            console.log("on data: " + js); // Not working :(
        });
    }
});

send.php

sio_message("Message","Data");

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);
    } else {
        echo "Connected<br>";
    }
    $bytes = socket_write($socket, json_encode(Array("msg" => $message, "data" => $data)));
    echo " $bytes bytes written";
    socket_close($socket);
}
9
  • So you got two socket server listening on the same port 8080? Commented Dec 9, 2018 at 4:45
  • Sorry if it was unclear, it’s just two different options, only one running at one time. But php shouldn’t care about this since it’s connection to the socket, right? Commented Dec 9, 2018 at 4:47
  • Can you confirm that the method is firing at all? does console.log ever fire? Is the problem the json.parse erroring with your json data? Any errors in your logs? I'm just wondering if it's ever making it into that final message at all. I'd be interested in seeing the raw data that's sent. Maybe https is doing something with it compared to http? I ran the original code on an http server so I'm wondering if that's the issue. Let me know what the raw data looks like Commented Dec 9, 2018 at 9:40
  • 1
    All console logs run except the most inner one, but I will try and move it above the JSON.parse method. I’m running node interactively and there were no message in the console. Is there any other error logs in node except what you seen on the screen? Commented Dec 9, 2018 at 9:51
  • Just add a console.log(buf) and let me know if you see anything there :3 I don't think so - I'd check your php logs for errors too if you can. Commented Dec 9, 2018 at 9:55

2 Answers 2

0

This might not have anything to do with the problem, but I did end up having to configure Apache to handle a Rewrite condition (I'm running Apache and Node.js side by side)

I figured I'd put the code here in case it helps anyone.

In httpd.conf I added the following code:

RewriteEngine On
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule .* ws://localhost:8080%{REQUEST_URI} [P]

ProxyRequests Off
ProxyPass        /socket.io http://localhost:8080/socket.io retry=0
ProxyPassReverse /socket.io http://localhost:8080/socket.io retry=0

ProxyPass "/node" "http://localhost:8080/"

Maybe missing that is an issue? I'm not sure - also /node becomes a direct link to the node.js server.

Sign up to request clarification or add additional context in comments.

Comments

-1

Try this:

var fs = require('fs');
var privateKey  = fs.readFileSync('my-domain-com.key', 'utf8');
var certificate = fs.readFileSync('my-domain-com.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var app = require('express')();
var https = require('https').createServer(credentials, app);
var io = require('socket.io')(https);

https.listen(8080, function(){
  console.log('Server online');
});

io.on("connection", function(client) {
    client.on('join', function(data) {

        io.emit('message',{sendto: all, message: 'Hello there! Welcome!'});

    });
    client.on('message', function(data) {
        console.log(data);

        //forward this message to specific user
        io.emit('message',data);
    });
});

PHP Script:

$message = json_encode(Array("msg" => $message, "data" => $data));
$msg_length = strlen($message);
$bytes = socket_write($socket, $message, $msg_length);

2 Comments

Thanks, but it still doesn't receive what PHP is sending. I'm confused about the difference between io.on and https.on. Does both get a "connection"? The io.on works when I connect with a frontend client using var socket = io(host + ':8080/');but not the direct socket call from PHP.
Nope, no difference, still no response on socket.on('data'). :( What is the "msg" for? Should it all be contained in something called 'data' somehow?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.