Benim temel PHP Soket Sunucu optimizasyonu ihtiyacı var mı?

2 Cevap php

Birçok insan gibi, ben PHP ile bir çok şey yapabilirsiniz. Ben sürekli yüz yok bir sorun, diğer insanlar çok daha organize ve çok daha yapılandırılmış, çok temiz yapabiliyor olmasıdır. Bu aynı zamanda çok daha hızlı yürütme süreleri ve daha az hata ile sonuçlanır.

Ben sadece basit bir PHP Socket Server (gerçek çekirdek) yazmayı bitirdim ve ben çekirdeğini genişleyen başlamadan önce ben farklı ne yapmalıyım bana söyleyebilir size soruyorum. Böyle şifreli veri, kimlik doğrulama veya çok-Threading gibi iyileştirmeler hakkında sormuyorum.

Ben daha çok "belki? (PHP5 kullanarak) daha nesne yönelimli bir şekilde bunu yapmalıyız", ya da benzeri sorular hakkında merak ediyorum "senaryo iyi çalışır şekilde genel yapısı, ya da bazı şeyler farklı yapılmalı?" . Temel olarak, "Bu bir yuva sunucunun çekirdek çalışması gerektiğini nasıl?"

Aslında, ben sadece seni buraya kodunu göstermek eğer çoğunuz hemen iyileştirmeler için oda göreceksiniz düşünüyorum. Bana çok nazik olun. Teşekkürler!

#!/usr/bin/php -q
<?
// config
$timelimit = 180; // amount of seconds the server should run for, 0 = run indefintely
$address = $_SERVER['SERVER_ADDR']; // the server's external IP
$port = 9000; // the port to listen on
$backlog = SOMAXCONN; // the maximum of backlog  incoming connections that will be queued for processing

// configure custom PHP settings
error_reporting(1); // report all errors
ini_set('display_errors', 1); // display all errors
set_time_limit($timelimit); // timeout after x seconds
ob_implicit_flush(); // results in a flush operation after every output call

//create master IPv4 based TCP socket
if (!($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) die("Could not create master socket, error: ".socket_strerror(socket_last_error()));

// set socket options (local addresses can be reused)
if (!socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)) die("Could not set socket options, error: ".socket_strerror(socket_last_error()));

// bind to socket server
if (!socket_bind($master, $address, $port)) die("Could not bind to socket server, error: ".socket_strerror(socket_last_error()));

// start listening
if (!socket_listen($master, $backlog)) die("Could not start listening to socket, error: ".socket_strerror(socket_last_error()));

//display startup information
echo "[".date('Y-m-d H:i:s')."] SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n"; //max connections is a kernel variable and can be adjusted with sysctl
echo "[".date('Y-m-d H:i:s')."] Listening on ".$address.":".$port.".\n";
$time = time(); //set startup timestamp

// init read sockets array 
$read_sockets = array($master);

// continuously handle incoming socket messages, or close if time limit has been reached
while ((!$timelimit) or (time() - $time < $timelimit)) {
    $changed_sockets = $read_sockets;
    socket_select($changed_sockets, $write = null, $except = null, null);
    foreach($changed_sockets as $socket) {
    	if ($socket == $master) {
    		if (($client = socket_accept($master)) < 0) {
    			echo "[".date('Y-m-d H:i:s')."] Socket_accept() failed, error: ".socket_strerror(socket_last_error())."\n";
    			continue;
    		} else {
    			array_push($read_sockets, $client);
    			echo "[".date('Y-m-d H:i:s')."] Client #".count($read_sockets)." connected (connections: ".count($read_sockets)."/".SOMAXCONN.")\n";
    		}
    	} else {
    		$data = @socket_read($socket, 1024, PHP_NORMAL_READ); //read a maximum of 1024 bytes until a new line has been sent
    		if ($data === false) { //the client disconnected
    			$index = array_search($socket, $read_sockets);
    			unset($read_sockets[$index]);
    			socket_close($socket);
    			echo "[".date('Y-m-d H:i:s')."] Client #".($index-1)." disconnected (connections: ".count($read_sockets)."/".SOMAXCONN.")\n";
    		} else {
    			if ($data = trim($data)) { //remove whitespace and continue only if the message is not empty
    				switch ($data) {
    					case "exit": //close connection when exit command is given
    						$index = array_search($socket, $read_sockets);
    						unset($read_sockets[$index]);
    						socket_close($socket);
    						echo "[".date('Y-m-d H:i:s')."] Client #".($index-1)." disconnected (connections: ".count($read_sockets)."/".SOMAXCONN.")\n";
    						break;
    					default: //for experimental purposes, write the given data back
    						socket_write($socket, "\n you wrote: ".$data);
    				}
    			}
    		}
    	}
    }
}
socket_close($master); //close the socket
echo "[".date('Y-m-d H:i:s')."] SERVER CLOSED.\n";
?>

2 Cevap

Bir küçük bir şey, ben şahsen çıkış yerine sadece yankısını kullanarak bir işlev oluşturmak istiyorum, bu şekilde kolay, kapatmak vb biçimini değiştirmek için. Örneğin

function log($message = '')
{
    echo '['.date('Y-m-d H:i:s').']'.$message;
}

ve daha sonra da kullanabilirsiniz:

log("SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n");

yerine

echo "[".date('Y-m-d H:i:s')."] SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n";

Oh and be sure to use === yerine == otherwise you might get some odd results.

Olasılıkla genişletmek gibi bir işlevi içine anahtarı $ veri taşımak istiyorum.

Bir metin tabanlı bir protokol kullanarak konum gibi görünüyor Ayrıca bu yana, ilk seviye komutu almak ve geçerli komutları bir dizi karşı denetlemek için / Strtok patlayabilir isteyebilirsiniz. Ayrıca çağrı gönderme call_user_func_array aramak ve kullanmak için ne iç işlevini açıklayan bir dizi olabilir.