Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes works, sometimes doesn't #14

Open
TyraelElDruin opened this issue Feb 21, 2018 · 8 comments
Open

Sometimes works, sometimes doesn't #14

TyraelElDruin opened this issue Feb 21, 2018 · 8 comments

Comments

@TyraelElDruin
Copy link

I'm hoping to use this on something I'm working on as a simple way to pass notifications to clients.

The issue I'm running into is that sometimes this works and sometimes it doesn't - there doesn't seem to be much rhyme or reason to it.

Sometimes it will instantly connect/disconnect without sending the message along - other times, it succeeds.

Have you tried using this to send multiple requests in succession?

@TyraelElDruin
Copy link
Author

TyraelElDruin commented Feb 21, 2018

I just wanted to say that I can sort of workaround this for my purposes - I'd love to see a solution, but I can at least see that the php client has connected and fire an event to my clients that basically just says "update." It seems to work okay, but I'd like to hear if you have a solution.

Server:

io.on('connection', function(socket) {
  var ip = socket.request.headers['x-forwarded-for'] || socket.request.connection.remoteAddress;
  //localhost response
  if(ip == "::ffff:127.0.0.1") {
	io.emit('UpdateClients', "");
	console.log("Update Sent to Users");
  }

Client

  socket.on('UpdateClients', function(msg) {
      SomeTable.ajax.reload();
  });

@TyraelElDruin
Copy link
Author

TyraelElDruin commented Apr 17, 2018

For anyone looking for a similar solution, I ended up going with this.

https://stackoverflow.com/a/49864533/1274820

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.

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) {
    //If connection is from our server (localhost)
	if(s.remoteAddress; == "::ffff:127.0.0.1") {
		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! 😉

@bitkill
Copy link
Contributor

bitkill commented Apr 17, 2018

Hi, Nice writeup.

The power of socket.io is in maintaining connections open, and updating data without performing requests.
I've used this approach to solve a problem some time ago, but I ended up using redis as a fifo queue to pass data between php & nodejs. This is not optimal, having to install redis (I use docker-compose nowadays, so not much of a problem), but I think is a better solution for passing data from one side to another and vice-versa.

@TyraelElDruin
Copy link
Author

Correct me if I'm wrong, but can't you just leave the socket open and send data as needed?

@KitDevUA
Copy link

KitDevUA commented Mar 2, 2019

I solved this problem this way:
var io = require('socket.io')(app,{ pingInterval: 250, pingTimeout: 250, });
Just set up the server not to hang with every 2-5 request, as before. Tested on 10,000 requests per row - 100% of deliveries.
I understand that this method is bad, but I did not find a better solution.

@KitDevUA
Copy link

KitDevUA commented Apr 3, 2019

I found better solution. The previous version overloads the server when large online.
New solution:

socket.on('ACTION', function (data) { // on event from php-library
	io.to(data.room).emit('ACTION', data); // sending data
	socket.disconnect(true); // disable connection due to php-library bug
});

@bitkill
Copy link
Contributor

bitkill commented Apr 5, 2019

Correct me if I'm wrong, but can't you just leave the socket open and send data as needed?

Sure, but php by definition creates an "instance" per request. This is great for REST api requests, but if you want to make a permanent solution, there are better alternatives. In my case I solved this by using redis to pass data to the node instance, and doing a proxy for the /socket.io/ location in nginx.

@EccoV
Copy link

EccoV commented May 27, 2021

I had the same problem as TyraelElDruin with this class. Sometimes my message arrived, sometimes it did not.

I solved it by placing a sleep(1) after the first fwrite().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants