Skip to content

Commit

Permalink
Merge pull request jookies#5 from nnikitos95/tryStreamSocketClient
Browse files Browse the repository at this point in the history
Try stream socket client
  • Loading branch information
nnikitos95 committed Mar 14, 2019
2 parents ee507f0 + 5a475f2 commit 9fd163b
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 49 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
}
],
"require": {
"php": ">=7.0"
"php": ">=7.0",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^7.4"
Expand Down
14 changes: 11 additions & 3 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,22 @@
<php>
<ini name="error_reporting" value="-1"/>
<env name="SHELL_VERBOSITY" value="-1"/>
<env name="jasmin_admin_host" value="172.20.0.2"/>
<env name="jasmin_admin_port" value="8990"/>
<env name="jasmin_admin_username" value="artemy"/>
<env name="jasmin_admin_password" value="artemy"/>
<env name="jasmin_read_write_wait_time" value="50000"/>
<!-- Uncomment if need run test on real server-->
<!--<env name="jasmin_real_server" value="1" />-->
<env name="jasmin_real_server" value="1" />
</php>

<testsuites>
<testsuite name="Connection">
<directory>tests/Connection</directory>
</testsuite>
<testsuite name="Command/Validator">
<directory>tests/Command/Validator</directory>
</testsuite>
<testsuite name="Command/Group">
<directory>tests/Command/Group</directory>
</testsuite>
Expand All @@ -27,8 +35,8 @@
<testsuite name="Command/Smpp">
<directory>tests/Command/SmppConnector</directory>
</testsuite>
<testsuite name="Command/Validator">
<directory>tests/Command/Validator</directory>
<testsuite name="Command/Filter">
<directory>tests/Command/Filter</directory>
</testsuite>
</testsuites>

Expand Down
11 changes: 8 additions & 3 deletions src/Jasmin/Command/AddTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ public function add(array $data, string &$errorStr = ''): bool
$errorStr = json_encode($validator->getErrors());
return false;
}
$this->session->runCommand($this->getName() . ' -a');

$command = $this->getName() . ' -a';
$command .= PHP_EOL;

foreach ($data as $property_key => $property_value) {
$this->session->runCommand($property_key . ' ' . $property_value);
$command .= $property_key . ' ' . $property_value;
$command .= PHP_EOL;
}

$result = $this->session->runCommand('ok');
$command .= 'ok' . PHP_EOL;

$result = $this->session->runCommand($command, $this->isHeavy());
if (false !== stripos($result, 'successfully')) {
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Jasmin/Command/BaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ public function __construct(Session $session)
}

abstract protected function getName(): string;

abstract protected function isHeavy(): bool;
}
5 changes: 5 additions & 0 deletions src/Jasmin/Command/Filter/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,9 @@ protected function parseList(array $exploded): array

return $filters;
}

protected function isHeavy(): bool
{
return false;
}
}
5 changes: 5 additions & 0 deletions src/Jasmin/Command/Group/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ protected function getAddValidator(): AddValidator
{
return new GroupAddValidator();
}

protected function isHeavy(): bool
{
return false;
}
}
9 changes: 7 additions & 2 deletions src/Jasmin/Command/SmppConnector/Connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected function parseList(array $exploded): array
*/
public function enable(string $key): bool
{
$r = $this->session->runCommand($this->getName() . ' -1 ' . $key);
$r = $this->session->runCommand($this->getName() . ' -1 ' . $key , true);
return $this->parseResult($r);
}

Expand All @@ -76,7 +76,12 @@ public function enable(string $key): bool
*/
public function disable(string $key)
{
$r = $this->session->runCommand($this->getName() . ' -0 ' . $key);
$r = $this->session->runCommand($this->getName() . ' -0 ' . $key, true);
return $this->parseResult($r);
}

protected function isHeavy(): bool
{
return true;
}
}
5 changes: 5 additions & 0 deletions src/Jasmin/Command/User/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,9 @@ protected function parseShow(array $exploded): array

return $options;
}

protected function isHeavy(): bool
{
return false;
}
}
38 changes: 24 additions & 14 deletions src/Jasmin/Connection/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ public static function init(string $username, string $password, SocketConnection
throw new \InvalidArgumentException('Not set username or password');
}

$connection->write("$username\r");
$connection->write("$password\r");
$connection->write(chr(0));
$connection->write($username . PHP_EOL);
$connection->write($password . PHP_EOL);
// $connection->write(chr(0));

$result = $connection->read();
if (false !== strpos($result, 'Incorrect')) {
Expand All @@ -46,30 +46,40 @@ public static function init(string $username, string $password, SocketConnection

/**
* @param string $command
* @param bool $needWaitBeforeRead
* @return bool|string
*
* @throws ConnectorException
*/
public function runCommand(string $command)
public function runCommand(string $command, bool $needWaitBeforeRead = false)
{
if (!$this->connection->isAlive()) {
throw new ConnectorException('Try execute command without open socket');
}

$command = trim($command) . "\r";
$command = trim($command) . PHP_EOL;

$this->connection->write($command, false);
$this->connection->write( ' ');
$this->connection->write($command);

return $this->connection->read();
if ($needWaitBeforeRead) {
$this->connection->wait();
}

return $this->normalize($this->connection->read(), strlen($command));
}

/**
* @return bool|string
* @throws ConnectorException
*/
public function persist()
protected function normalize(string $string, int $length): string
{
return substr(str_replace('jcli :', '', trim($string)), $length);
}

public function persist(string $profile = 'jcli-prod')
{
$this->runCommand('persist ' . $profile);
}

public function load(string $profile = 'jcli-prod')
{
return $this->runCommand('persist');
$this->runCommand('load ' . $profile);
}
}
61 changes: 39 additions & 22 deletions src/Jasmin/Connection/SocketConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ class SocketConnection
* Time for sleeping between command
* @var int
*/
const DEFAULT_SLEEP_TIME = 10000;
const LOGIN_SLEEP_TIME = 100000;
const DEFAULT_BUFFER_SIZE = 2048;
const DEFAULT_SLEEP_TIME = 50000;

/**
* @var resource
Expand All @@ -35,18 +33,21 @@ private function __construct($fp, int $sleepTime)
{
$this->fp = $fp;
$this->sleepTime = $sleepTime;
$this->read();
}

/**
* @param string $host
*
* @param int $port
* @param int $sleepTime Time for sleeping between command
*
* @param int $waitTime
*
* @return SocketConnection
*
* @throws ConnectionException
*/
public static function init(string $host, int $port, int $sleepTime = self::DEFAULT_SLEEP_TIME): SocketConnection
public static function init(string $host, int $port, int $waitTime = self::DEFAULT_SLEEP_TIME): SocketConnection
{
if (!is_int($port)) {
throw new ConnectionException('Invalid port');
Expand All @@ -56,32 +57,42 @@ public static function init(string $host, int $port, int $sleepTime = self::DEFA
throw new ConnectionException('Invalid server ip');
}

$errno = $errstr = null;
set_error_handler(function ($_errno, $_errstr) use (&$errno, &$errstr) {
$errno = $_errno;
$errstr = $_errstr;
}, E_WARNING);
$start = -microtime(true);

$fp = fsockopen($host, $port, $errno, $errstr);
if (!$resource = @stream_socket_client("tcp://$host:$port", $errno, $errstr)) {
throw new \RuntimeException($errstr);
}

restore_error_handler();
$start += microtime(true);
$start *= 1000;

if (!$fp) {
throw new ConnectionException('Unable open connection, errno: ' . $errno . ', errstr: ' . $errstr);
}
$rwtimeout = (float) $start;
$rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
$timeoutSeconds = floor($rwtimeout);
$timeoutUSeconds = ($rwtimeout - $timeoutSeconds) * 1000000;
stream_set_timeout($resource, $timeoutSeconds, $timeoutUSeconds);

return new self($fp, $sleepTime < self::DEFAULT_SLEEP_TIME ? self::DEFAULT_SLEEP_TIME : $sleepTime);
return new self($resource, $waitTime < self::DEFAULT_SLEEP_TIME ? self::DEFAULT_SLEEP_TIME : $waitTime);
}

/**
* @param string $str
* @param bool $needSleep
* @throws \Exception
*/
public function write(string $str, bool $needSleep = true)
public function write(string $str)
{
fwrite($this->fp, $str);
if ($needSleep) {
usleep($this->sleepTime);
while (($length = strlen($str)) > 0) {
$written = @fwrite($this->fp, $str);

if ($length === $written) {
return;
}

if ($written === false || $written === 0) {
throw new \RuntimeException('Error while writing bytes to the server.');
}

$str = substr($str, $written);
}
}

Expand All @@ -91,11 +102,12 @@ public function write(string $str, bool $needSleep = true)
*/
public function read(int $bytes = null)
{
return str_replace('jcli: >', '', fread($this->fp, $bytes ?? self::DEFAULT_BUFFER_SIZE));
return fread($this->fp, $bytes ?? 8192);
}

public function disconnect()
{
fclose($this->fp);
$this->fp = null;
}

Expand All @@ -106,4 +118,9 @@ public function isAlive(): bool
{
return $this->fp !== null;
}

public function wait()
{
usleep($this->sleepTime);
}
}
7 changes: 6 additions & 1 deletion tests/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class BaseTest extends TestCase
*/
protected function getConnection(): SocketConnection
{
return SocketConnection::init($this->getHost(), $this->getPort(), 50000);
return SocketConnection::init($this->getHost(), $this->getPort(), $this->getWaitTime());
}

/**
Expand Down Expand Up @@ -79,4 +79,9 @@ public function isRealJasminServer(): bool
{
return getenv('jasmin_real_server') ? true : false;
}

public function getWaitTime(): int
{
return getenv('jasmin_read_write_wait_time') ?: 1000000;
}
}
18 changes: 15 additions & 3 deletions tests/Command/Filter/FilterCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,30 @@
use JasminWeb\Jasmin\Command\Filter\Filter;
use JasminWeb\Jasmin\Command\Group\Group;
use JasminWeb\Jasmin\Command\User\User;
use JasminWeb\Test\Command\BaseCommandTest;
use JasminWeb\Jasmin\Connection\Session;
use JasminWeb\Test\BaseTest;
use PHPUnit\Framework\MockObject\MockObject;

class FilterCommandTest extends BaseCommandTest
class FilterCommandTest extends BaseTest
{
/**
* @var MockObject|Session
*/
private $session;

/**
* @var Filter
*/
private $filter;

public function setUp()
{
parent::setUp();
if (!$this->session && $this->isRealJasminServer()) {
$this->session = $this->getSession();
} else {
$this->session = $this->getSessionMock();
}

$this->filter = new Filter($this->session);
}

Expand Down

0 comments on commit 9fd163b

Please sign in to comment.