Some work

This commit is contained in:
Alex Solomaha
2016-08-19 17:48:27 +03:00
parent c5ae61fddb
commit aa2b4c40fc
5 changed files with 92 additions and 77 deletions

View File

@@ -5,17 +5,36 @@ namespace app\components;
use app\models\Item;
use linslin\yii2\curl\Curl;
use Yii;
use yii\base\Component;
use yii\helpers\Json;
class ApiHelper
class ApiHelper extends Component implements ApiHelperInterface
{
/**
* @var Item
*/
public $item;
/**
* ApiHelper constructor.
* @param Item $item
*/
public function __construct(Item $item)
{
parent::__construct();
$this->item = $item;
return $this;
}
/**
* Get CURL instance
*
* @param int $timeout
* @return Curl
*/
public static function getCurl($timeout = 2)
public function getCurl($timeout = 2)
{
$curl = new Curl();
$curl->setOption(CURLOPT_TIMEOUT, $timeout);
@@ -26,9 +45,9 @@ class ApiHelper
/**
* @return string
*/
public static function getBaseUrl($item)
public function getBaseUrl()
{
return Yii::$app->params['apiBaseUrl'];
return $this->item->board->baseUrl;
}
/**
@@ -37,21 +56,19 @@ class ApiHelper
* @param $url
* @return array
*/
public static function makeRequest($url)
public function makeRequestToApi($url)
{
$curl = self::getCurl();
$response = $curl->get(self::getBaseUrl() . $url);
$response = $this->getCurl()->get($this->getBaseUrl() . $url);
return Json::decode($response);
}
/**
* @param Item $item
* @return mixed
*/
public static function getItemValue($item)
public function getValue()
{
$data = self::makeRequest($item->url);
$data = $this->makeRequestToApi($this->item->url);
return $data['value'];
}
@@ -59,22 +76,20 @@ class ApiHelper
/**
* Turn item on and return current state
*
* @param Item $item
* @return boolean
* @return array
*/
public static function itemTurnOn($item)
public function turnOn()
{
return self::makeRequest($item->url . '/1');
return $this->makeRequestToApi($this->item->url . '/1');
}
/**
* Turn item off and return current state
*
* @param Item $item
* @return boolean
* @return array
*/
public static function itemTurnOff($item)
public function turnOff()
{
return self::makeRequest($item->url . '/0');
return $this->makeRequestToApi($this->item->url . '/0');
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace app\components;
interface ApiHelperInterface
{
public function getCurl($timeout = 2);
public function getBaseUrl();
public function makeRequestToApi($url);
public function getValue();
}

View File

@@ -4,7 +4,9 @@ use yii\helpers\ArrayHelper;
$params = [
'adminEmail' => 'admin@example.com',
'apiBaseUrl' => 'http://176.36.54.229',
'auth' => [
'tokenExpireSec' => 2,
],
];
return ArrayHelper::merge($params, require 'params-local.php');
return ArrayHelper::merge($params, require 'params-local.php');

View File

@@ -33,6 +33,9 @@ class Item extends ActiveRecord
const TYPE_VARIABLE_BOOLEAN = 25;
const TYPE_VARIABLE_BOOLEAN_DOOR = 26;
const VALUE_ON = 1;
const VALUE_OFF = 0;
/**
* @inheritdoc
*/

View File

@@ -8,6 +8,7 @@ use app\models\Item;
use app\models\User;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
use Ratchet\WebSocket\Version\RFC6455\Connection;
use React\EventLoop\LoopInterface;
use Yii;
use yii\helpers\Json;
@@ -65,7 +66,7 @@ class Panel implements MessageComponentInterface
$this->items[$item->id] = $item;
if ($item->save_history_interval > 0) {
$this->loop->addPeriodicTimer($item->save_history_interval, function () {
$this->loop->addPeriodicTimer($item->save_history_interval, function () use ($item) {
$this->saveHistory($item);
});
}
@@ -80,8 +81,36 @@ class Panel implements MessageComponentInterface
// Get query
$query = $conn->WebSocket->request->getQuery();
// Welcome user
return $this->auth($conn, $query);
$id = $query->get('id');
$time = $query->get('time');
$token = $query->get('token');
if ((time() - $time) >= Yii::$app->params['auth']['tokenExpireSec']) {
return $this->log("Auth failed (Token expired). ID: $id; Token: $token; IP: {$conn->remoteAddress}; Timestamp: $time");
}
// Find user by auth info
/** @var User $user */
$user = User::findOne([
'id' => $id,
'auth_key' => $token,
]);
// Security checks
if (!$user) {
return $this->log("Auth failed. ID: $id; Token: $token; IP: {$conn->remoteAddress}; Timestamp: $time");
}
// Close previous connection
if (isset($this->clients[$user->id])) {
$this->clients[$user->id]->close();
}
// Attach to online users
$conn->User = $user;
$this->clients[$user->id] = $conn;
return $this->log("Connected new user [$id] {$user->username}");
}
public function onMessage(ConnectionInterface $from, $msg)
@@ -95,7 +124,7 @@ class Panel implements MessageComponentInterface
/** @var User $user */
$user = $from->User;
$data = json_decode($msg, true);
$data = Json::decode($msg);
if ($data['type'] === 'switch') {
return $this->handleSwitch($from, $user, $data);
@@ -118,57 +147,12 @@ class Panel implements MessageComponentInterface
public function onError(ConnectionInterface $conn, \Exception $e)
{
// Logging
echo "An error has occurred: {$e->getMessage()} in file {$e->getFile()} at line {$e->getLine()}" . PHP_EOL;
echo "Error: {$e->getMessage()} in file {$e->getFile()} at line {$e->getLine()}" . PHP_EOL;
// Close connection
$conn->close();
}
/**
* Authenticate connected user
*
* @param ConnectionInterface $conn
* @param $query
* @return bool
*/
protected function auth(ConnectionInterface $conn, $query)
{
$id = $query->get('id');
$time = $query->get('time');
$token = $query->get('token');
if ((time() - $time) >= Yii::$app->params['auth']['tokenExpireSec']) {
echo 'Token expired' . PHP_EOL;
return false;
}
// Find user by auth info
/** @var User $user */
$user = User::findOne([
'id' => $id,
'auth_key' => $token,
]);
// Security checks
if (!$user) {
echo 'Wrong token or id: steamID: "' . $id . '", token: "' . $token . '", IP: ' . $conn->remoteAddress . ', time: ' . $time . PHP_EOL;
return false;
}
// Close previous connection
if (isset($this->clients[$user->id])) {
$this->clients[$user->id]->close();
}
// Attach to online users
$conn->User = $user;
$this->clients[$user->id] = $conn;
return true;
}
/**
* @param ConnectionInterface $from
* @param User $user
@@ -195,9 +179,10 @@ class Panel implements MessageComponentInterface
]);
}
ApiHelper::itemTurnOn($item);
$api = new ApiHelper($item);
$api->turnOn();
return $this->saveHistory($item, 1);
return $this->saveHistory($item, Item::VALUE_ON);
}
/**
@@ -219,7 +204,7 @@ class Panel implements MessageComponentInterface
*
* @param integer $user_id
* @param array $data
* @return bool
* @return bool|mixed
*/
private function sendTo($user_id, $data)
{
@@ -227,9 +212,7 @@ class Panel implements MessageComponentInterface
/** @var ConnectionInterface $client */
$client = $this->clients[$user_id];
$client->send(Json::encode($data));
return true;
return $client->send(Json::encode($data));
}
return false;
@@ -254,7 +237,8 @@ class Panel implements MessageComponentInterface
{
if ($value === null) {
try {
$value = ApiHelper::getItemValue($item);
$api = new ApiHelper($item);
$value = $api->getValue();
} catch (\Exception $e) {
return false;
}