Overview

Namespaces

  • None
  • sinacloud
    • sae

Classes

  • SaeADPNS
  • SaeAPNS
  • SaeChannel
  • SaeDeferredJob
  • SaeFetchInternal
  • SaeKV
  • SaeMail
  • SaeMysql
  • SaeSegment
  • SaeTAdvance
  • SaeTaskQueue
  • SaeTClientV2
  • SaeTOAuthV2
  • SaeVCode
  • sinacloud\sae\Storage
  • vDisk

Exceptions

  • OAuthException
  • sinacloud\sae\StorageException
  • Overview
  • Namespace
  • Class
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 
<?php
/**
 * SAE Channel 服务
 *
 * Demo 地址:{@link https://github.com/sinacloud/sae-channel-examples/tree/master/php}
 *
 * <code>
 * <?php
 * $channel = new SaeChannel();
 * $connection = $channel->createChannel('test',100);
 * $message_content = 'hello,sae';
 * // Send message
 * $ret = $channel->sendMessage('test',$message_content);
 *
 * ?>
 * </code>
 *
 * 错误码参考:
 *  - errno: 0        成功
 *  - errno: 101    参数错误
 *  - errno: 500    服务内部错误
 *
 * @package sae
 * @author Lazypeople <lazy@changes.com.cn>
 *
 */

class SaeChannel extends SaeObject
{
    const end_ = 'http://channel.sae.sina.com.cn:81/v1/';
    const MAXIMUM_CLIENT_ID_LENGTH_ = 256;
    const MAXIMUM_TOKEN_DURATION_SECONDS_ = 7200;
    const MAXIMUM_MESSAGE_LENGTH_ = 4096;
    private $_accesskey = '';
    private $_secretkey = '';
    private $errMsg = 'success';
    private $errNum = 0;

    /**
     */
    function __construct()
    {
        $this->_accesskey = SAE_ACCESSKEY;
        $this->_secretkey = SAE_SECRETKEY;
    }

    /**
     * 创建一个channel信道
     *
     * @param string $name channel的名称
     * @param int $duration channel的有效时间,单位为秒,默认为1小时
     * @return string
     * @author Lazypeople
     */
    public function createChannel($name, $duration = 3600)
    {
        $check_ret = $this->check_client_id($name) && $this->check_duration($duration);
        if (!$check_ret) {
            return false;
        }
        $request_url = SaeChannel::end_ . 'create_channel';
        $post_data = array('client_id' => $name, 'duration' => $duration);
        $post_data = http_build_query($post_data);
        $ret = $this->postData($request_url, $post_data);
        return $ret;
    }

    /**
     * 发送一条消息
     *
     * 上行发送一条消息,向客户端推送消息,最大可以发送4k的消息,最好不要直接发送二进制的数据。
     *
     * @param string $name channel的名称
     * @param string $message 需要发送的消息内容
     * @param boolean $async 是否返回消息发送的结果,如果设置为true,服务端会立刻返回(始终返回成功)
     * @return boolean
     * @author Lazypeople
     */
    public function sendMessage($name, $message, $async = False)
    {
        $check_ret = $this->check_client_id($name) && $this->check_message($message);
        if (!$check_ret) {
            return false;
        }
        $request_url = SaeChannel::end_ . 'send_message';
        $post_data = array('client_id' => $name, 'message' => $message, 'async' => $async ? 1 : 0);
        $post_data = http_build_query($post_data);
        $ret = $this->postData($request_url, $post_data);
        return $ret && true;
    }

    /**
     * 取得错误信息
     *
     * @return string
     * @author Lazypeople
     */
    public function errmsg()
    {
        $ret = $this->errMsg;
        $this->errMsg = 'success';
        return $ret;
    }

    /**
     * 取得错误码
     *
     * @return int
     * @author Lazypeople
     */
    public function errno()
    {
        $ret = $this->errNum;
        $this->errNum = 0;
        return $ret;
    }

    /**
     * @ignore
     */
    private function set_error($errno, $errmsg)
    {
        $this->errNum = $errno;
        $this->errMsg = $errmsg;
    }

    /**
     * @ignore
     */
    private function check_client_id($client_id)
    {
        if (strlen($client_id) > SaeChannel::MAXIMUM_CLIENT_ID_LENGTH_) {
            $errmsg = sprintf('Client id length %d is greater than max length %d', strlen($client_id), SaeChannel::MAXIMUM_CLIENT_ID_LENGTH_);
            $this->set_error(101, $errmsg);
            return false;
        }
        return true;
    }

    /**
     * @ignore
     */
    private function check_duration($duration)
    {
        if (!$duration) {
            $errmsg = NULL;
            if ($duration < 1) {
                $errmsg = 'Argument duration must not be less than 1';
            } elseif ($duration > SaeChannel::MAXIMUM_TOKEN_DURATION_SECONDS_) {
                $errmsg = sprintf('Argument duration must be less than %d', (SaeChannel::MAXIMUM_TOKEN_DURATION_SECONDS_ + 1));
            }
            if (!is_null($errmsg)) {
                $this->set_error(101, $errmsg);
                return false;
            }
        }
        return true;
    }

    /**
     * @ignore
     */
    private function check_message($message)
    {
        $errmsg = NULL;
        if (is_null($message)) {
            $errmsg = 'Argument message must not be null';
        } elseif (strlen($message) > SaeChannel::MAXIMUM_MESSAGE_LENGTH_) {
            $errmsg = sprintf('Message must be no longer than %d chars', SaeChannel::MAXIMUM_MESSAGE_LENGTH_);
        }
        if (!is_null($errmsg)) {
            $this->set_error(101, $errmsg);
            return false;
        }
        return true;
    }

    /**
     * @ignore
     */
    private function postData($url, $post)
    {
        $s = curl_init();
        curl_setopt($s, CURLOPT_URL, $url);
        curl_setopt($s, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($s, CURLOPT_TIMEOUT, 10);
        curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($s, CURLOPT_HEADER, 0);
        curl_setopt($s, CURLINFO_HEADER_OUT, true);
        curl_setopt($s, CURLOPT_HTTPHEADER, $this->genReqestHeader($post));
        curl_setopt($s, CURLOPT_POST, true);
        curl_setopt($s, CURLOPT_POSTFIELDS, $post);
        $ret = curl_exec($s);
        $info = curl_getinfo($s);
        curl_close($s);
        if (empty($info['http_code'])) {
            $errmsg = "Channel service internal error:" . curl_error($s);
            $this->set_error(SAE_ErrInternal, $errmsg);
        } else if ($info['http_code'] != 200) {
            $errmsg = "Channel service internal error: {$info['http_code']}";
            $this->set_error(SAE_ErrInternal, $errmsg);
        } else {
            $ret = json_decode($ret, true);
            if ($ret && array_key_exists('data', $ret)) {
                return $ret['data'];
            } else {
                $this->set_error(102, $ret['error']);
            }
            return $ret['data'];
        }
        return false;
    }

    /**
     * @ignore
     */
    private function genSignature($content, $secretkey)
    {
        $sig = base64_encode(hash_hmac('sha256', $content, $secretkey, true));
        return $sig;
    }

    /**
     * @ignore
     */
    private function genReqestHeader($post)
    {
        $timestamp = date('Y-m-d H:i:s');
        $cont1 = "ACCESSKEY" . $this->_accesskey . "TIMESTAMP" . $timestamp;
        $reqhead = array("TimeStamp: $timestamp", "AccessKey: " . $this->_accesskey, "Signature: " . $this->genSignature($cont1, $this->_secretkey));
        return $reqhead;
    }
}
API documentation generated by ApiGen