Permalink
Browse files

add async service for plugin

  • Loading branch information...
joyqi committed Nov 15, 2017
1 parent 5f3620e commit f180e8452de92a99d189779a67b6caf1ce2b26cf
Showing with 174 additions and 4 deletions.
  1. +11 −0 var/Helper.php
  2. +34 −1 var/Typecho/Common.php
  3. +39 −0 var/Typecho/Response.php
  4. +1 −0 var/Typecho/Router.php
  5. +1 −1 var/Widget/Ajax.php
  6. +88 −2 var/Widget/Service.php
@@ -63,6 +63,17 @@ public static function widgetById($table, $pkId)
return $widget;
}
/**
* 请求异步服务
*
* @param $method
* @param $params
*/
public static function requestService($method, $params)
{
Typecho_Widget::widget('Widget_Service')->requestService($method, $params);
}
/**
* 强行删除某个插件
*
@@ -22,7 +22,7 @@
class Typecho_Common
{
/** 程序版本 */
const VERSION = '1.1/17.10.30';
const VERSION = '1.1/17.11.15';
/**
* 允许的属性
@@ -910,6 +910,39 @@ public static function hashValidate($from, $to)
}
}
/**
* 创建一个会过期的Token
*
* @param $secret
* @return string
*/
public static function timeToken($secret)
{
return sha1($secret . '&' . time());
}
/**
* 在时间范围内验证token
*
* @param $token
* @param $secret
* @param int $timeout
* @return bool
*/
public static function timeTokenValidate($token, $secret, $timeout = 5)
{
$now = time();
$from = $now - $timeout;
for ($i = $now; $i >= $from; $i --) {
if (sha1($secret . '&' . $i) == $token) {
return true;
}
}
return false;
}
/**
* 将路径转化为链接
*
@@ -87,6 +87,13 @@ class Typecho_Response
*/
private static $_instance = null;
/**
* 结束前回调函数
*
* @var array
*/
private static $_callbacks = array();
/**
* 获取单例句柄
*
@@ -126,6 +133,33 @@ private function _parseXml($message)
}
}
/**
* 结束前的统一回调函数
*/
public static function callback()
{
static $called;
if ($called) {
return;
}
$called = true;
foreach (self::$_callbacks as $callback) {
call_user_func($callback);
}
}
/**
* 新增回调
*
* @param $callback
*/
public static function addCallback($callback)
{
self::$_callbacks[] = $callback;
}
/**
* 设置默认回执编码
*
@@ -211,6 +245,7 @@ public function throwXml($message)
'</response>';
/** 终止后续输出 */
self::callback();
exit;
}
@@ -229,6 +264,7 @@ public function throwJson($message)
echo Json::encode($message);
/** 终止后续输出 */
self::callback();
exit;
}
@@ -246,9 +282,11 @@ public function redirect($location, $isPermanently = false)
$location = Typecho_Common::safeUrl($location);
if ($isPermanently) {
self::callback();
header('Location: ' . $location, false, 301);
exit;
} else {
self::callback();
header('Location: ' . $location, false, 302);
exit;
}
@@ -296,6 +334,7 @@ public function goBack($suffix = NULL, $default = NULL)
$this->redirect($default);
}
self::callback();
exit;
}
}
@@ -138,6 +138,7 @@ public static function dispatch()
$widget->{$route['action']}();
}
Typecho_Response::callback();
return;
} catch (Exception $e) {
@@ -51,7 +51,7 @@ public function checkVersion()
/** 匹配内容体 */
$response = $client->getResponseBody();
$json = json_decode($response, true);
$json = Json::decode($response, true);
if (!empty($json)) {
list($soft, $version) = explode(' ', $this->options->generator);
@@ -19,6 +19,13 @@
*/
class Widget_Service extends Widget_Abstract_Options implements Widget_Interface_Do
{
/**
* 异步请求
*
* @var array
*/
public $asyncRequests = array();
/**
* 发送pingback实现
*
@@ -31,7 +38,13 @@ public function sendPingHandle()
$this->user->pass('contributor');
/** 忽略超时 */
ignore_user_abort(true);
if (function_exists('ignore_user_abort')) {
ignore_user_abort(true);
}
if (function_exists('set_time_limit')) {
set_time_limit(30);
}
/** 获取post */
$post = $this->widget('Widget_Archive', "type=post", "cid={$this->request->cid}");
@@ -138,7 +151,7 @@ public function sendPing($cid, array $trackback = NULL)
$client->setCookie('__typecho_uid', Typecho_Cookie::get('__typecho_uid'))
->setCookie('__typecho_authCode', Typecho_Cookie::get('__typecho_authCode'))
->setHeader('User-Agent', $this->options->generator)
->setTimeout(3)
->setTimeout(2)
->setData($input)
->send(Typecho_Common::url('/action/service', $this->options->index));
@@ -148,6 +161,78 @@ public function sendPing($cid, array $trackback = NULL)
}
}
/**
* 请求异步服务
*
* @param $method
* @param mixed $params
*/
public function requestService($method, $params = NULL)
{
static $called;
if (!$called) {
$self = $this;
Typecho_Response::addCallback(function () use ($self) {
if (!empty($self->asyncRequests) && $client = Typecho_Http_Client::get()) {
try {
$client->setHeader('User-Agent', $this->options->generator)
->setTimeout(2)
->setData(array(
'do' => 'async',
'requests' => Json::encode($self->asyncRequests),
'token' => Typecho_Common::timeToken($this->options->secret)
))
->setMethod(Typecho_Http_Client::METHOD_POST)
->send(Typecho_Common::url('/action/service', $this->options->index));
} catch (Typecho_Http_Client_Exception $e) {
return;
}
}
});
$called = true;
}
$this->asyncRequests[] = array($method, $params);
}
/**
* 执行回调
*
* @throws Typecho_Widget_Exception
*/
public function asyncHandle()
{
/** 验证权限 */
$token = $this->request->token;
if (!Typecho_Common::timeTokenValidate($token, $this->options->secret, 3)) {
throw new Typecho_Widget_Exception(_t('禁止访问'), 403);
}
/** 忽略超时 */
if (function_exists('ignore_user_abort')) {
ignore_user_abort(true);
}
if (function_exists('set_time_limit')) {
set_time_limit(30);
}
$requests = Json::decode($this->request->requests, true);
$plugin = Typecho_Plugin::factory(__CLASS__);
if (!empty($requests)) {
foreach ($requests as $request) {
list ($method, $params) = $request;
$plugin->{$method}($params);
}
}
}
/**
* 异步请求入口
*
@@ -157,5 +242,6 @@ public function sendPing($cid, array $trackback = NULL)
public function action()
{
$this->on($this->request->is('do=ping'))->sendPingHandle();
$this->on($this->request->is('do=async'))->asyncHandle();
}
}

0 comments on commit f180e84

Please sign in to comment.