Skip to content

Commit

Permalink
Merge pull request #9 from navarr/viniciusjarina-add_timeout
Browse files Browse the repository at this point in the history
Merge in Timeout Feature & Code Style Changes
  • Loading branch information
navarr committed Feb 23, 2015
2 parents 7f1ba77 + 3c668e2 commit 91e8cea
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 70 deletions.
11 changes: 11 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Path-based git attributes
# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html

# Ignore all test and documentation with "export-ignore".

/examples export-ignore
/tests export-ignore
/.travis.yml export-ignore
/phpunit.xml export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/
atlassian-ide-plugin.xml
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ before_script:
- composer require --dev phpunit/phpunit 3.7.18
- wget https://scrutinizer-ci.com/ocular.phar
script:
- phpunit --bootstrap=bootstrap.php --coverage-clover=coverage.clover --coverage-text="php://stdout" --configuration="phpunit.xml" src/Navarr/Socket/Tests
- vendor/bin/phpunit --coverage-clover=coverage.clover --configuration="phpunit.xml"
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
9 changes: 0 additions & 9 deletions bootstrap.php

This file was deleted.

4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Navarr/Socket",
"name": "navarr/sockets",
"description": "Sockets in PHP",
"minimum-stability": "stable",
"authors": [
Expand All @@ -19,7 +19,7 @@
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {
"psr-4": {
"Navarr\\Socket\\": "src/"
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/EchoServer.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?php

// run composer install in top directory
require_once('../vendor/autoload.php');
require_once(__DIR__ . '/../vendor/autoload.php');

use Navarr\Socket\Socket;
use Navarr\Socket\Server;
use Navarr\Socket\Socket;

class EchoServer extends Server
{
Expand Down
21 changes: 11 additions & 10 deletions examples/WebServer.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?php

// run composer install in top directory
require_once('../vendor/autoload.php');
require_once(__DIR__ . '/../vendor/autoload.php');

use Navarr\Socket\Socket;
use Navarr\Socket\Server;
use Navarr\Socket\Socket;

class WebServer extends Server
{
Expand All @@ -24,22 +24,22 @@ public function __construct($address = null, $port = 80)
public function onConnect(Server $server, Socket $client, $message)
{
echo "Connection\n";
$this->clientMap[(string)$client] = new WebClient($server, $client);
$this->clientMap[(string) $client] = new WebClient($server, $client);
}

public function onInput(Server $server, Socket $client, $message)
{
$messages = explode("\n", $message);
foreach ($messages as $message) {
$message .= "\n";
$this->clientMap[(string)$client]->dispatch($message);
$this->clientMap[(string) $client]->dispatch($message);
}
}

public function onDisconnect(Server $server, Socket $client, $message)
{
echo "Disconnect\n";
unset($this->clientMap[(string)$client]);
unset($this->clientMap[(string) $client]);
}
}

Expand Down Expand Up @@ -68,25 +68,26 @@ public function dispatch($message)
echo trim($message), "\n";
$message = trim($message);
if ($this->firstLine === null) {
$tokens = explode(" ", $message, 3);
$this->verb = $tokens[0];
$tokens = explode(" ", $message, 3);
$this->verb = $tokens[0];
$this->resource = $tokens[1];
$this->protocol = $tokens[2];

$this->firstLine = $message;
$this->lastLine = $message;
$this->lastLine = $message;

return;
}
if ($message !== '') {
$tokens = explode(": ", $message, 2);
$tokens = explode(": ", $message, 2);
$this->headers[$tokens[0]] = $tokens[1];
}
if ($this->lastLine === '' && $message === '') {
$this->writeLine('HTTP/1.1 200 OK');
$this->writeLine('Content-Type: text/plain');
$this->writeLine();

$url = $this->headers['Host'].$this->resource;
$url = $this->headers['Host'] . $this->resource;
$this->writeLine(
"You requested {$url} using verb {$this->verb} over {$this->protocol}"
);
Expand Down
26 changes: 12 additions & 14 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
<phpunit bootstrap="bootstrap.php">
<phpunit bootstrap="./tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnFailure="false"
>
<testsuites>
<testsuite name="Navarr/Sockets Tests">
<directory>src/Navarr/Socket/Tests</directory>
<testsuite name="Sockets Test Suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
<exclude>
<directory suffix=".php">src/Navarr/Socket/Tests</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="coverage" />
<log type="coverage-text" target="php://stdout" />
<log type="coverage-html" target="coverage"/>
<log type="coverage-text" target="php://stdout"/>
</logging>
</phpunit>
</phpunit>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public function __construct($message = null)
} elseif (is_resource($message)) {
$errno = socket_last_error($message);
} else {
parent::__construct((string)$message);
parent::__construct((string) $message);

return;
}

Expand Down
45 changes: 38 additions & 7 deletions src/Navarr/Socket/Server.php → src/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ class Server
*/
protected $port;

/**
* Seconds to wait on a socket before timing out
* @var int|null
*/
protected $timeout = null;

/**
* Domain
* @see http://php.net/manual/en/function.socket-create.php
Expand Down Expand Up @@ -75,6 +81,11 @@ class Server
*/
const HOOK_DISCONNECT = '__NAVARR_SOCKET_SERVER_DISCONNECT__';

/**
* Constant String for Server Timeout
*/
const HOOK_TIMEOUT = '__NAVARR_SOCKET_SERVER_TIMEOUT__';

/**
* Return value from a hook callable to tell the server not to run the other hooks
*/
Expand All @@ -90,12 +101,15 @@ class Server
*
* @param string $address An IPv4, IPv6, or Unix socket address
* @param int $port
* @param int $timeout Seconds to wait on a socket before timing it out
*/
public function __construct($address, $port = 0)
public function __construct($address, $port = 0, $timeout = null)
{
set_time_limit(0);
$this->address = $address;
$this->port = $port;
$this->port = $port;
$this->timeout = $timeout;

switch (true) {
case filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4):
$this->domain = AF_INET;
Expand Down Expand Up @@ -145,14 +159,20 @@ protected function loopOnce()
$read = array_merge(array($this->masterSocket), $this->clients);

// Set up a block call to socket_select
$write = null;
$write = null;
$except = null;
Socket::select($read, $write, $except, null);
$ret = Socket::select($read, $write, $except, $this->timeout);
if ($this->timeout != null && $ret == 0) {
if ($this->triggerHooks(self::HOOK_TIMEOUT, $this->masterSocket) === false) {
// This only happens when a hook tells the server to shut itself down.
return false;
}
}

// If there is a new connection, add it
if (in_array($this->masterSocket, $read)) {
unset($read[array_search($this->masterSocket, $read)]);
$socket = $this->masterSocket->accept();
$socket = $this->masterSocket->accept();
$this->clients[] = $socket;

if ($this->triggerHooks(self::HOOK_CONNECT, $socket) === false) {
Expand Down Expand Up @@ -191,7 +211,9 @@ protected function loopOnce()

/**
* Overrideable Read Functionality
*
* @param Socket $client
*
* @return string
*/
protected function read(Socket $client)
Expand All @@ -201,14 +223,16 @@ protected function read(Socket $client)

/**
* Disconnect the supplied Client Socket
*
* @param Socket $client
* @param string $message Disconnection Message. Could be used to trigger a disconnect with a status code
*
* @return bool Whether or not to continue running the server (true: continue, false: shutdown)
*/
public function disconnect(Socket $client, $message = '')
{
$clientIndex = array_search($client, $this->clients);
$return = $this->triggerHooks(
$return = $this->triggerHooks(
self::HOOK_DISCONNECT,
$this->clients[$clientIndex],
$message
Expand All @@ -229,9 +253,11 @@ public function disconnect(Socket $client, $message = '')

/**
* Triggers the hooks for the supplied command
* @param string $command Hook to listen for (e.g. HOOK_CONNECT, HOOK_INPUT, HOOK_DISCONNECT)
*
* @param string $command Hook to listen for (e.g. HOOK_CONNECT, HOOK_INPUT, HOOK_DISCONNECT, HOOK_TIMEOUT)
* @param Socket $client
* @param string $input Message Sent along with the Trigger
*
* @return bool Whether or not to continue running the server (true: continue, false: shutdown)
*/
protected function triggerHooks($command, Socket $client, $input = null)
Expand All @@ -249,14 +275,17 @@ protected function triggerHooks($command, Socket $client, $input = null)
unset($continue);
}
}

return true;
}

/**
* Attach a Listener to a Hook
*
* @param string $command Hook to listen for
* @param callable $callable A callable with the signature (Server, Socket, string).
* Callable should return false if it wishes to stop the server, and true if it wishes to continue.
*
* @return void
*/
public function addHook($command, $callable)
Expand All @@ -276,8 +305,10 @@ public function addHook($command, $callable)

/**
* Remove the provided Callable from the provided Hook
*
* @param string $command Hook to remove callable from
* @param callable $callable The callable to be removed
*
* @return void
*/
public function removeHook($command, $callable)
Expand Down
Loading

0 comments on commit 91e8cea

Please sign in to comment.