摘要:背景前段時間遷移小米推送部分代碼,這部分之前是其他人負(fù)責(zé)的。并行推送端實體端實體推送結(jié)果以上就是這些了,通過以上的方式我們就用很少的代碼封裝了一個小米,目前只實現(xiàn)了按登記別名用戶賬號標(biāo)簽多標(biāo)簽全體推送。
背景
前段時間遷移小米推送部分代碼,這部分之前是其他人負(fù)責(zé)的。讀了代碼,發(fā)現(xiàn)了兩點:
所有接口的實現(xiàn)除了url和傳參基本都是一致的
android和ios的設(shè)備需要分別推送一次
剛好這段時間了解了一下php的重載概念【動態(tài)的創(chuàng)建類屬型和方法,不同于java等的參數(shù)不同方法名相通的概念,具體的概念可以RTFM】和curl的并發(fā)方式,所以
對于以上第一點:是否可以利用php的重載概念,用魔術(shù)方法__call()動態(tài)的變更接口調(diào)用的url參數(shù)和請求參數(shù),去實現(xiàn)對小米推送不同接口的調(diào)用,也就是說我們所有的調(diào)用邏輯都是實現(xiàn)在__call這一個方法中,卻對外提供小米推送不同接口的調(diào)用方法,這樣就會極大的簡化代碼
對于以上第二點:是否可以利用curl的并行方式一次性推送給android和ios設(shè)備,這樣理論上我們可以減少一次推送調(diào)用的時間,因為我們不需要再去等待給一類設(shè)備推送完了,再去推送給另一類設(shè)備
/** * 運行環(huán)境 develop:開發(fā)環(huán)境 product:生產(chǎn)環(huán)境 * @var string */ private $_environment = "develop"; /** * 設(shè)備系統(tǒng)類型 android ios * @var string */ private $_osType = ""; /** * 小米推送域名 * @var string */ private $_host = ""; /** * 請求頭 * @var string */ private $_headers = ""; /** * 接口url * @var string */ private $_url = ""; /** * 調(diào)用的接口方法名稱 * @var array */ private $_function = []; /** * 請求參數(shù) * @var array */ private $_data = []; /** * 小米推送設(shè)置 * @var array */ private $_options = [ "title" => "消息通知自定義title", "restricted_package_name" => "", "pass_through" => 0, // 0 通知欄消息 1 透傳 "notify_type" => -1, // -1:默認(rèn)所有,1:使用默認(rèn)提示音提示,2:使用默認(rèn)震動提示,4:使用默認(rèn)led燈光提示 "time_to_send" => 0, // 定時推送 單位毫秒 默認(rèn)0 ]; /** * 運行環(huán)境配置 * @var array */ private static $_environmentConfig = [ "domain" => [ "product" => "https://api.xmpush.xiaomi.com/", "develop" => "https://sandbox.xmpush.xiaomi.com/" ], ]; /** * 小米推送接口信息定義 * * url/請求參數(shù) * @var array */ private $_functionDefine = [ "regid" => [ "uri" => "v3/message/regid", "arguments" => [ "registration_id" => [ "type" => "array", "must" => "y" ], "description" => [ "type" => "string", "must" => "y" ], "params" => [//自定義參數(shù) "type" => "array", "must" => "n" ], ] ], "userAccount" => [ "uri" => "v2/message/user_account", "arguments" => [ "user_account" => [ "type" => "array", "must" => "y" ], "description" => [ "type" => "string", "must" => "y" ], "params" => [//自定義參數(shù) "type" => "array", "must" => "n" ], ] ], "alias" => [ "uri" => "v3/message/alias", "arguments" => [ "alias" => [ "type" => "array", "must" => "y" ], "description" => [ "type" => "string", "must" => "y" ], "params" => [//自定義參數(shù) "type" => "array", "must" => "n" ], ] ], "topic" => [ "uri" => "v3/message/topic", "arguments" => [ "topics" => [ "type" => "array", "must" => "y" ], "description" => [ "type" => "string", "must" => "y" ], "params" => [//自定義參數(shù) "type" => "array", "must" => "n" ], ] ], "multiTopic" => [ "uri" => "v3/message/multi_topic", "arguments" => [ "topics" => [ "type" => "array", "must" => "y" ], "topics_op" => [// UNION并集,INTERSECTION交集,EXCEPT差集 "type" => "string", "must" => "y" ], "description" => [ "type" => "string", "must" => "y" ], "params" => [//自定義參數(shù) "type" => "array", "must" => "n" ], ] ], "all" => [ "uri" => "v3/message/all", "arguments" => [ "description" => [ "type" => "string", "must" => "y" ], "params" => [//自定義參數(shù) "type" => "array", "must" => "n" ], ] ], ];mipush實體的構(gòu)造函數(shù):實現(xiàn)對一系列配置的初始化
/** * 初始化配置 * * @param $string $os_type 系統(tǒng)類型 * @param $string $config 配置 * @param array $options 設(shè)置 [ * "title" => "string,標(biāo)題", * "pass_through" => "tinyint,0通知欄消息,1透傳,默認(rèn)0" * "notify_type" => "tinyint,-1,1,2,3,4", * "time_to_send" => "int, 定時推送, 毫秒" * ] * @param string $environment 環(huán)境 */ public function __construct($os_type="", $config=array(), $options=array(), $environment="") { /* init environment */ if ($environment) { $this->_environment = $environment; } if ($os_type === "ios") { $this->_host = self::$_environmentConfig["domain"][$this->_environment];// ios }else{ $this->_host = self::$_environmentConfig["domain"]["product"];// android } /* init option */ $this->_headers = []; $this->_headers[] = "Authorization: key=" . $config["secret"]; if ($os_type === "android") { $this->_options["restricted_package_name"] = $config["package_name"]; } foreach ($this->_options as $k => &$v) { if (in_array($k, $options)) { $v = $options[$k]; } } }mipush實體的魔法方法__call:動態(tài)實現(xiàn)對小米推送接口的參數(shù)驗證和調(diào)用,以至于我們未來實現(xiàn)新的小米推送接口及實現(xiàn)配置就可以。
/** * 魔術(shù)方法 * * 重載對象方法 * @param string $name 小米推送方法名稱 * @param array $arguments 請求參數(shù) * @return mixed void||object */ public function __call($name,$arguments) { $arguments = $arguments[0]; $this->_function = $this->_functionDefine[$name]; $this->_url = $this->_host . $this->_function["uri"]; $this->dataCheck($arguments); switch ($name) { case "regid": $this->_data["registration_id"] = $arguments["registration_id"]; break; case "userAccount": $this->_data["user_account"] = implode(",", $arguments["user_account"]); break; case "alias": $this->_data["alias"] = implode(",", $arguments["alias"]); break; case "topic": $this->_data["topic"] = $arguments["topic"]; break; case "multiTopic": $this->_data["topics"] = implode(";$;", $arguments["topics"]); $this->_data["topic_op"] = $arguments["topic_op"]; break; case "all": $this->_data["topics"] = implode(";$;", $topics); $this->_data["topic_op"] = "UNION"; break; default: throw new Exception("Sorry, This function is useless in this version", 404); break; } $this->_data["description"] = $arguments["description"]; if($arguments["params"]) { foreach ($arguments["params"] as $k => $v) { $this->_data["extra.".$k] = $v;// 自定義參數(shù) } } if ($this->_osType === "android") { $this->_data = array_merge($this->_data, $this->_options); } }
定義完小米推送實體后,我們只需要通過mipush這個實體,實例化生產(chǎn)不同設(shè)備類型的對象,再由curl并行的方式發(fā)起推送即可。
/** * 并行推送 * * @param Mipush $mipush_ios ios端實體 * @param Mipush $mipush_android android端實體 * @return array 推送結(jié)果 */ private static function curlRequest(Mipush $mipush_ios, Mipush $mipush_android) { $ch_ios = curl_init(); $ch_android = curl_init(); curl_setopt($ch_ios, CURLOPT_URL, $mipush_ios->_url); curl_setopt($ch_ios, CURLOPT_POST, 1); curl_setopt($ch_ios, CURLOPT_POSTFIELDS, $mipush_ios->_data); curl_setopt($ch_ios, CURLOPT_HTTPHEADER, $mipush_ios->_headers); curl_setopt($ch_ios, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch_android, CURLOPT_URL, $mipush_android->_url); curl_setopt($ch_android, CURLOPT_POST, 1); curl_setopt($ch_android, CURLOPT_POSTFIELDS, $mipush_android->_data); curl_setopt($ch_android, CURLOPT_HTTPHEADER, $mipush_android->_headers); curl_setopt($ch_android, CURLOPT_RETURNTRANSFER, 1); $mh = curl_multi_init(); curl_multi_add_handle($mh, $ch_ios); curl_multi_add_handle($mh, $ch_android); $running=null; do { curl_multi_exec($mh,$running); } while($running > 0); $result["ios"] = json_decode(curl_multi_getcontent($ch_ios), true); $result["android"] = json_decode(curl_multi_getcontent($ch_android), true); curl_multi_remove_handle($mh, $ch_ios); curl_multi_remove_handle($mh, $ch_android); curl_multi_close($mh); return $result; }
以上就是這些了,通過以上的方式我們就用很少的代碼封裝了一個小米sdk,目前只實現(xiàn)了按regid(登記id),alias(別名),user_account(用戶賬號),topic(標(biāo)簽), multi_topic(多標(biāo)簽),all(全體)推送。
composer require tigerb/easy-mipush 使用格式: try { Push::init( ["secret" => "string,必傳,ios密鑰"], ["secret" => "string,必傳,android密鑰", "package_name" => "string,必傳,android包名"] [ "title" => "string,非必傳,消息通知自定義title", "pass_through" => "int,非必傳,0通知欄消息,1透傳,默認(rèn)0", "notify_type" => "int,非必傳,-1:默認(rèn)所有,1:使用默認(rèn)提示音提示,2:使用默認(rèn)震動提示,4:使用默認(rèn)led燈光提示", "time_to_send" => "int,非必傳,定時推送,單位毫秒,默認(rèn)0", ], "string,develop開發(fā)環(huán)境,product生產(chǎn)環(huán)境, 默認(rèn)develop" ); $res = Push::toUse("string,小米push方法名", "array, 該方法對應(yīng)的參數(shù)"); echo json_encode($res, JSON_UNESCAPED_UNICODE); } catch (Exception $e) { echo $e->getMessage(); } 使用示例: use MipushPush; require "./vendor/autoload.php"; try { Push::init( ["secret" => "test"], ["secret" => "test", "package_name" => "com.test"], [ "title" => "test", "pass_through" => 0, "notify_type" => -1, "time_to_send" => 0, ], "develop" ); $res = Push::toUse("userAccount", [ "user_account" => [1], "description" => "test" ]); echo json_encode($res, JSON_UNESCAPED_UNICODE); } catch (Exception $e) { echo $e->getMessage(); }
最后,第一次寫這種文章,寫的不是很好,寫的不對的地方謝謝大家留言指證出來,其次,還沒驗證過這里使用魔術(shù)方法的性能消耗,因為之前有看過鳥哥的文章不贊成使用魔術(shù)方法,歡迎大家留言指證,謝謝。
完整代碼地址: https://github.com/TIGERB/eas...
掃面下方二維碼關(guān)注我的技術(shù)公眾號,及時為大家推送我的原創(chuàng)技術(shù)分享
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/21940.html
摘要:我看可以發(fā)現(xiàn)小米推送目錄結(jié)構(gòu)是這樣的其中是底層的網(wǎng)絡(luò)庫,主要是封裝了的和方法請求遠(yuǎn)程的服務(wù)器并利用提供的類來接收服務(wù)器返回的數(shù)據(jù),代碼十分優(yōu)雅,我們可以看看。 小米推送框架 近期因為有需要稍微看了一下小米推送的 php 版本服務(wù)端框架,這個推送平臺免費的,我們只需要告訴小米平臺我們要推什么設(shè)備,它會自己幫我們推,而且還會統(tǒng)計很多信息給我們分析,如抵達率和點擊率等等,當(dāng)然客戶端也要用小米...
摘要:下面我們正式開始嘗試小米推送,首先,找出其業(yè)務(wù)邏輯中的一個節(jié)點。因為小米推送是商業(yè)產(chǎn)品,這里不便于探索太多內(nèi)容,但是通過這個插件可以比較方便的進行類似的研究。 前言 有時候我們在Java開發(fā)過程中可能有這樣的需求:需要研究或者修改工程依賴的Jar包中的一些邏輯,查看代碼運行中Jar包代碼內(nèi)部的取值情況(比如了解SDK與其服務(wù)器通信的請求報文加密前的情況)。 這個需求類似于Hook。 但...
閱讀 1700·2021-11-02 14:47
閱讀 3648·2019-08-30 15:44
閱讀 1334·2019-08-29 16:42
閱讀 1731·2019-08-26 13:53
閱讀 935·2019-08-26 10:41
閱讀 3458·2019-08-23 17:10
閱讀 597·2019-08-23 14:24
閱讀 1717·2019-08-23 11:59