Authored by wuxiao

监听直播房间商品推送

缓存键组件
<?php
namespace backend\controllers;
use Yii;
use common\components\cachekey\Parser;
/**
* Ajax controller
*/
class AjaxController extends BaseController
{
/**
* 监听直播房间商品推送记录
*/
public function actionPushgoodslog()
{
$log = Yii::$app->redisIm->rpop(Parser::load('room/product/pushlog'));
$this->renderJson(Yii::$app->params['success_code'],'',(string)$log);
}
}
... ...
... ... @@ -12,6 +12,8 @@ $this->registerJsFile('/js/php.js',array('postion'=>View::POS_END));
<?php $this->beginBlock('javascript');?>
var i = 0;
var room_id = <?=$room->room_id?>;
var interval_handle;
var default_interval = 3;
/**
* 推送商品
* @param {type} product_id
... ... @@ -36,6 +38,12 @@ function sendProduct(product_id){
_sendProduct(product_id);
},function(evt){
consoleLog('收到消息: '+evt.data);
data = JSON.parse(evt.data);
if (data.status == 1){
consoleLog('请求推送成功');
}else{
consoleLog('请求推送失败');
}
},function(){
consoleLog('连接已关闭');
},function(){
... ... @@ -47,7 +55,7 @@ function sendProduct(product_id){
}
function _sendProduct(product_id){
consoleLog('发推送,商品ID: '+product_id);
consoleLog('发推送,商品ID: '+product_id);
cmd = {cmd:10001,room:room_id,skn:product_id};
cmd['secret'] = makeSign(cmd);
... ... @@ -58,6 +66,24 @@ function _sendProduct(product_id){
ws.send(cmd);
//ws.send('{"cmd":"10001","skn":"123","room":"3","secret":"72c1f9eb60b761d3078294e3e8318fc0"}');
//ws.close();
getPushlog(default_interval);
}
/**
*
* @param {type} package
* @returns {unresolved}
*/
function getPushlog(interval){
clearInterval(interval_handle);
interval_handle = setInterval(function(){
$.get('/ajax/pushgoodslog','',function(json){
console.log(json);
if (json.data){
consoleLog('监听到推送记录: '+json.data);
}
},'json');
},interval*1000);
$('#pushlog').text('推送记录监听中...');
}
/**
* 页面打印发送记录
... ... @@ -142,6 +168,12 @@ $this->registerJs($this->blocks['javascript'],View::POS_END)
</div>
<div class="form-group">
<label>
<button type="button" onclick="getPushlog(default_interval)" id="pushlog" class="btn btn-primary">开始监听推送记录</button>
</label>
</div>
<div class="form-group">
<div class="col-sm-6" id="runtime">
</div>
</div><!-- form-group -->
\ No newline at end of file
... ...
... ... @@ -10,6 +10,11 @@ use Yii;
*/
class Parser{
//路径
private $path;
//待替换参数
private $params;
/**
* 缓存句柄
* @var type
... ... @@ -40,19 +45,43 @@ class Parser{
$this->cache = Yii::createObject('yii\caching\ArrayCache');
}
static function get($path,$params){
/**
* 载入路径
* @param type $path
* @param type $params
* @return type
*/
static function load($path,$params = []){
$self = self::self();
$self->path = $path;
if (func_num_args() > 2){
$params = func_get_args();
array_shift($params);
}
$self->params = $params;
return $self;
}
/**
* 获取最终键名
* @return type
*/
public function key(){
$path = $this->path;
$params = $this->params;
$main_key = 'get'.$path.serialize($params);
if ($realkey = $self->cache->get($main_key)){
if ($realkey = $this->cache->get($main_key)){
return $realkey;
}
$key = 'cacheKey'.$path;
if (!$cachekey = $self->cache->get($key)){
if (!$cachekey = $this->cache->get($key)){
$cache = basename($path);
$dir = dirname($path);
if (!$cacheMap = $self->read($dir)){
if (!$cacheMap = $this->read($dir)){
self::$error = 'cannot read '.$path;
return;
}
... ... @@ -61,13 +90,9 @@ class Parser{
return;
}
$cachekey = $cacheMap[$cache];
$self->cache->set($key,$cachekey,$self->expire);
}
if (func_num_args() > 2){
$params = func_get_args();
array_shift($params);
$this->cache->set($key,$cachekey,$this->expire);
}
if (is_array($params)){
if (!is_list($params)){
$dict = $list = [];
... ... @@ -89,11 +114,25 @@ class Parser{
$realkey = sprintf($realkey,$params);
}
$realkey = $path.':'.$realkey;
$self->cache->set($main_key,$realkey,$self->expire);
$realkey = $this->addPrefix($realkey);
$this->cache->set($main_key,$realkey,$this->expire);
return $realkey;
}
/**
* 添加前缀
* @param type $key
* @return type
*/
private function addPrefix($key){
return strtr(Yii::$app->params['cache_prefix'].':'.$key,array('::'=>':'));
}
/**
* 读取文件
* @param type $path
* @return boolean
*/
private function read($path){
$key = __FUNCTION__.$path;
if (!$content = $this->cache->get($key)){
... ...
<?php
return [
//直播房间商品弹框推送记录(队列)
'pushlog'=>'push_goods_log',
];
\ No newline at end of file
... ...
<?php
namespace common\components\caching;
use Yii;
use yii\db\Exception;
use common\components\cachekey\Parser;
class RedisCache extends \yii\redis\Connection
{
/**
* Initializes the object.
* This method is invoked at the end of the constructor after the object is initialized with the
* given configuration.
*/
public function init()
{
}
/**
* Allows issuing all supported commands via magic methods.
*
* ```php
* $redis->hmset(['test_collection', 'key1', 'val1', 'key2', 'val2'])
* ```
*
* @param string $name name of the missing method to execute
* @param array $params method call arguments
* @return mixed
*/
public function __call($name, $params)
{
$key = $params[0];
if ($key instanceof Parser){
$params[0] = $key->key();
}
return parent::__call($name, $params);
}
/**
* Establishes a DB connection.
* It does nothing if a DB connection has already been established.
* @throws Exception if connection fails
*/
public function open()
{
if ($this->_socket !== false) {
return;
}
$connection = ($this->unixSocket ?: $this->hostname . ':' . $this->port) . ', database=' . $this->database;
\Yii::trace('Opening redis DB connection: ' . $connection, __METHOD__);
$this->_socket = @stream_socket_client(
$this->unixSocket ? 'unix://' . $this->unixSocket : 'tcp://' . $this->hostname . ':' . $this->port,
$errorNumber,
$errorDescription,
$this->connectionTimeout ? $this->connectionTimeout : ini_get("default_socket_timeout"),
$this->socketClientFlags
);
if ($this->_socket) {
if ($this->dataTimeout !== null) {
stream_set_timeout($this->_socket, $timeout = (int) $this->dataTimeout, (int) (($this->dataTimeout - $timeout) * 1000000));
}
if ($this->password !== null) {
$this->executeCommand('AUTH', [$this->password]);
}
//$this->executeCommand('SELECT', [$this->database]);
$this->initConnection();
} else {
\Yii::error("Failed to open redis DB connection ($connection): $errorNumber - $errorDescription", __CLASS__);
$message = YII_DEBUG ? "Failed to open redis DB connection ($connection): $errorNumber - $errorDescription" : 'Failed to open DB connection.';
throw new Exception($message, $errorDescription, (int) $errorNumber);
}
}
/**
* Closes the currently active DB connection.
* It does nothing if the connection is already closed.
*/
public function close()
{
if ($this->_socket !== false) {
$connection = ($this->unixSocket ?: $this->hostname . ':' . $this->port) . ', database=' . $this->database;
\Yii::trace('Closing DB connection: ' . $connection, __METHOD__);
//$this->executeCommand('QUIT');
stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR);
$this->_socket = null;
}
}
}
\ No newline at end of file
... ...
... ... @@ -2,6 +2,7 @@
namespace common\components\pagecache;
use Yii;
use common\components\cachekey\Parser;
/**
* @author wuxiao
... ... @@ -19,6 +20,14 @@ class Redis extends \yii\redis\Cache
}
parent::init();
}
public function buildKey($key)
{
if ($key instanceof Parser){
$key = $key->key();
}
return parent::buildKey($key);
}
/**
* @inheritdoc
... ...
... ... @@ -12,7 +12,7 @@ return [
'keyPrefix' => 'YOHOLive',
],
'redis' => [
'class' => 'yii\redis\Connection',
'class' => 'common\components\caching\RedisCache',
'hostname' => '123.56.138.21',
'password' => 'yohoglobal',
'port' => 6379,
... ... @@ -21,7 +21,7 @@ return [
'dataTimeout' => 0.8,
],
'redisIm' => [
'class' => 'yii\redis\Connection',
'class' => 'common\components\caching\RedisCache',
'hostname' => '123.56.138.21',
'password' => 'yohoglobal',
'port' => 6379,
... ...
... ... @@ -238,7 +238,7 @@ class Connection extends Component
/**
* @var resource redis socket connection
*/
private $_socket = false;
protected $_socket = false;
/**
... ...