MagisterMundus
MagisterMundus

Reputation: 335

PHP Sockets on Linux - Free tcp port immediately after/when php exits via command?

I have a nginx server running a php script 24/7 that receives messages via sockets and stores them using mysql.

Sometimes I have to stop it running for a reason or another and I need a way to have it restart as soon as possible in order to avoid losing messages.

I use this script (.sh) to stop and run the process again:

pkill -f socketserver.php
#<Line that frees the tcp port>
/usr/bin/php /var/www/webroot/ROOT/socketserver.php #uses tcp port: 20491

If I don't use the command that frees the tcp port, I have (and will have) to wait something between 2 and 5 minutes until the OS perceives there is no process using that tcp port and frees/releases it.

Should I use: fuser, tcpkill, what? I prefer things that are already installed on the ubuntu server 14.04

Thank you.

Upvotes: 0

Views: 805

Answers (2)

wrigby
wrigby

Reputation: 126

Building on @Joni's answer, you'll want to use the socket_set_option() function before binding your socket (http://php.net/manual/en/function.socket-set-option.php - and yes, this code is shamelessly copy/pasted from that page):

if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
    echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL;
}

Once you use this, subsequent restarts of the script should work fine, without the need to manually free the socket.

Upvotes: 2

Joni
Joni

Reputation: 111219

You cannot forcibly "free" a TCP port. To remove the obligatory wait time, the socket server should set the SO_REUSEADDR socket option when it creates the listening socket.

This way you'll still lose messages if the server is busy when you restart it. A better solution is doing what other people do: have a "master" process create and bind the listening socket, and delegate accepting connections and working on them to a child process. Most reasons you have for restarting, like reloading config, can be done by restarting the child only, while the listening socket stays open for connections.

Upvotes: 3

Related Questions