Reputation: 149
I am currently working on this project (php) where I have to connect my php backend to a remote server using sockets. I am using this code to create the connection and it works fine:
$key=base64_encode(openssl_random_pseudo_bytes(16));
$head = "GET / HTTP/1.1"."\r\n".
"Upgrade: WebSocket"."\r\n".
"Pragma: no-cache"."\r\n".
"Accept-Encoding: gzip, deflate"."\r\n".
"Connection: Upgrade"."\r\n".
"Origin: http://$host"."\r\n".
"Host: $host"."\r\n".
"Sec-WebSocket-Version: 13"."\r\n".
"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits"."\r\n".
"Sec-WebSocket-Protocol: b_xmlproc"."\r\n".
"Cache-Control: no-cache"."\r\n".
"Sec-WebSocket-Key: $key"."\r\n".
"Content-Length: 0\r\n"."\r\n";
$sock = pfsockopen($host, $port, $errno, $errstr, 2);
fwrite($sock, $head ) or die('error:'.$errno.':'.$errstr);
I trigger this code through an HTTP call and I am trying to avoid creating multiple sockets. For the moment, every time I am triggering this endpoint, a new socket is created. However, I would like to use pre-existing socket if one has been created already instead of a new one. Here is what I tried so far, without success.
$GLOBALS = array('globalsocket' => null);
but the variable is re-created every time a new request is triggered.If anyone has a clue on how to do that, I would much appreciate ! Thanks.
PS: I must note that I am used to nodejs and not php, which may be the reason why I am having a hard time figuring it out
PPS: I don't have any database where I can store it
Here is how I would do what I want i nodejs
var net = require("net");
const http = require("http");
let client = new net.Socket();
let connected = false;
const requestListener = function (req, res) {
console.log("status", client.listening);
if (!connected) {
client.connect("port", "ip", function () {
console.log("Connected");
connected = true;
});
}
res.writeHead(200);
res.end("Hello, World!");
};
const server = http.createServer(requestListener);
client.on("data", function (data) {
console.log("Received: " + data);
client.destroy(); // kill client after server's response
});
client.on("close", function () {
connected = false;
console.log("Connection closed");
});
client.on("end", function(){
console.log("Connection end");
connected = false;
client.destroy()
})
client.on('error', function(){
console.log("Connection end");
connected = false;
client.destroy()
})
server.listen("xxx");
Upvotes: 0
Views: 1297
Reputation: 1059
PHP is works just like HTTP, basically stateless will initiate execution every-time it gets new request. We sometime might need to run background jobs and process for which we need to utillize crontab or similar scheduler.
Note: PHP process is blocking IO so you can though use cli on server and keep it running to entertain all your request but that will be reinventing the wheel.
I'd suggest use: http://socketo.me/docs/hello-world
From example on above link
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {
}
public function onMessage(ConnectionInterface $from, $msg) {
}
public function onClose(ConnectionInterface $conn) {
}
public function onError(ConnectionInterface $conn, \Exception $e) {
}
}
You can keep using these 4 function to achieve everything. However you might need your custom logic to prevent your session or auth data.
this also use a background process which you need to execute on server.
php bin/chat-server.php
and you can use any custom script to check and keep it running if interrupted, just like you use pm2 or supervisor for node.
Try and update us if this works for you.
Upvotes: 0
Reputation: 491
PHP is not a long-running process like Node. Given only the portion of code you provided, the PHP process would start up, open socket, write, and quit. This process would of course be repeated whenever you make a request to that PHP script.
To make a long running PHP script that acts as a server, you'd 1) need to run it from CLI (this is the only way you'll bypass max execution time, which is by default 30 seconds), and 2) you'd need a while loop or similar to keep it open indefinitely (or until some condition is met).
Perhaps you'd be more comfortable with a PHP library for this purpose.
Some things to consider:
http://socketo.me/ - PHP websocket server
https://github.com/ratchetphp/Pawl - PHP websocket client
Upvotes: 1