Support to run as TCP server & fork a child process for every connection (#183)
parent
ea92b224cd
commit
48e0167060
10
README.md
10
README.md
|
@ -148,6 +148,16 @@ Example:
|
|||
|
||||
php bin/php-language-server.php --tcp=127.0.0.1:12345
|
||||
|
||||
#### `--tcp-server=host:port` (optional)
|
||||
Causes the server to use a tcp connection for communicating with the language client instead of using STDIN/STDOUT.
|
||||
The server will listen on the given address for a connection.
|
||||
If PCNTL is available, will fork a child process for every connection.
|
||||
If not, will only accept one connection and the connection cannot be reestablished once closed, spawn a new process instead.
|
||||
|
||||
Example:
|
||||
|
||||
php bin/php-language-server.php --tcp-server=127.0.0.1:12345
|
||||
|
||||
#### `--memory-limit=integer` (optional)
|
||||
Sets memory limit for language server.
|
||||
Equivalent to [memory-limit](http://php.net/manual/en/ini.core.php#ini.memory-limit) php.ini directive.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use LanguageServer\{LanguageServer, ProtocolStreamReader, ProtocolStreamWriter};
|
||||
use Sabre\Event\Loop;
|
||||
|
||||
$options = getopt('', ['tcp::', 'memory-limit::']);
|
||||
$options = getopt('', ['tcp::', 'tcp-server::', 'memory-limit::']);
|
||||
|
||||
ini_set('memory_limit', $options['memory-limit'] ?? -1);
|
||||
|
||||
|
@ -31,21 +31,67 @@ set_exception_handler(function (\Throwable $e) {
|
|||
@cli_set_process_title('PHP Language Server');
|
||||
|
||||
if (!empty($options['tcp'])) {
|
||||
// Connect to a TCP server
|
||||
$address = $options['tcp'];
|
||||
$socket = stream_socket_client('tcp://' . $address, $errno, $errstr);
|
||||
if ($socket === false) {
|
||||
fwrite(STDERR, "Could not connect to language client. Error $errno\n");
|
||||
fwrite(STDERR, "$errstr\n");
|
||||
fwrite(STDERR, "Could not connect to language client. Error $errno\n$errstr");
|
||||
exit(1);
|
||||
}
|
||||
$inputStream = $outputStream = $socket;
|
||||
stream_set_blocking($socket, false);
|
||||
$ls = new LanguageServer(
|
||||
new ProtocolStreamReader($socket),
|
||||
new ProtocolStreamWriter($socket)
|
||||
);
|
||||
Loop\run();
|
||||
} else if (!empty($options['tcp-server'])) {
|
||||
// Run a TCP Server
|
||||
$address = $options['tcp-server'];
|
||||
$tcpServer = stream_socket_server('tcp://' . $address, $errno, $errstr);
|
||||
if ($tcpServer === false) {
|
||||
fwrite(STDERR, "Could not listen on $address. Error $errno\n$errstr");
|
||||
exit(1);
|
||||
}
|
||||
fwrite(STDOUT, "Server listening on $address\n");
|
||||
if (!extension_loaded('pcntl')) {
|
||||
fwrite(STDERR, "PCNTL is not available. Only a single connection will be accepted\n");
|
||||
}
|
||||
while ($socket = stream_socket_accept($tcpServer, -1)) {
|
||||
fwrite(STDOUT, "Connection accepted\n");
|
||||
stream_set_blocking($socket, false);
|
||||
if (extension_loaded('pcntl')) {
|
||||
// If PCNTL is available, fork a child process for the connection
|
||||
// An exit notification will only terminate the child process
|
||||
$pid = pcntl_fork();
|
||||
if ($pid === -1) {
|
||||
fwrite(STDERR, "Could not fork\n");
|
||||
exit(1);
|
||||
} else if ($pid === 0) {
|
||||
// Child process
|
||||
$ls = new LanguageServer(
|
||||
new ProtocolStreamReader($socket),
|
||||
new ProtocolStreamWriter($socket)
|
||||
);
|
||||
Loop\run();
|
||||
// Just for safety
|
||||
exit(0);
|
||||
}
|
||||
} else {
|
||||
// If PCNTL is not available, we only accept one connection.
|
||||
// An exit notification will terminate the server
|
||||
$ls = new LanguageServer(
|
||||
new ProtocolStreamReader($socket),
|
||||
new ProtocolStreamWriter($socket)
|
||||
);
|
||||
Loop\run();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$inputStream = STDIN;
|
||||
$outputStream = STDOUT;
|
||||
// Use STDIO
|
||||
stream_set_blocking(STDIN, false);
|
||||
$ls = new LanguageServer(
|
||||
new ProtocolStreamReader(STDIN),
|
||||
new ProtocolStreamWriter(STDOUT)
|
||||
);
|
||||
Loop\run();
|
||||
}
|
||||
|
||||
stream_set_blocking($inputStream, false);
|
||||
|
||||
$server = new LanguageServer(new ProtocolStreamReader($inputStream), new ProtocolStreamWriter($outputStream));
|
||||
|
||||
Loop\run();
|
||||
|
|
Loading…
Reference in New Issue