转载

从小米推送 php 服务端框架中看看代码该怎么写

小米推送框架

近期因为有需要稍微看了一下小米推送的 php 版本服务端框架,这个推送平台免费的,我们只需要告诉小米平台我们要推什么设备,它会自己帮我们推,而且还会统计很多信息给我们分析,如抵达率和点击率等等,当然客户端也要用小米平台提供的 sdk 来注册设备。我感觉这个代码写得挺优雅的,故分享一下我的看法。你可以去官网下载 sdk , 详细的文档在 这里 。

我看可以发现小米推送目录结构是这样的:

├── xmpush
   ├── Builder.php
   ├── Constants.php
   ├── DevTools.php
   ├── ErrorCode.php
   ├── Feedback.php
   ├── HttpBase.php
   ├── IOSBuilder.php
   ├── Message.php
   ├── Result.php
   ├── Sender.php
   ├── Stats.php
   ├── Subscription.php
   ├── TargetedMessage.php
   └── Tracer.php

其中 HttpBase.php 是底层的网络库,主要是封装了 HTTP 的 POST 和 GET 方法请求远程的服务器并利用 Result.php 提供的类来接收服务器返回的数据,代码十分优雅,我们可以看看。

//发送请求,获取result,带重试
    public function postResult($url,$fields,$retries){
        $result = new Result($this->postReq($url, $fields));
        if($result->getErrorCode() == ErrorCode::Success){
            return $result;
        }
        //重试
        for($i=0;$i<$retries;$i++){
            $result = new Result($this->postReq($url, $fields));
            if($result->getErrorCode() == ErrorCode::Success){
                break;
            }
        }
        return $result;
    }
    
    //post方式发送请求
    public function postReq($url,$fields,$timeout=10){
        $headers = array('Authorization: key=' . $this->appSecret, 
        'Content-Type: application/x-www-form-urlencoded');
        // Open connection
        $ch = curl_init();
    
        // Set the url, number of POST vars, POST data
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
        print_r('HTTP Params <br> '.urldecode(http_build_query($fields)));
        echo'<br>';
        // Execute post
        $result = curl_exec($ch);
            
        // Close connection
        curl_close($ch);
        return $result;
    }

从名字就可以看出,上面是利用 POST 方法请求小米服务器,返回值用result包装了一下,如果返回码不为 0,那么久重试一下。在发送请求的时候把发送的 field 打印出来,让开发者能看到请求的内容。虽然代码很简单,但是值得新手区学习这样的代码规范。有时候你自己写框架的时候也可以借鉴这种方式。

builder.php 实现的实例继承了 message 可以承载着我们的发送给服务端的消息数据,这就是我们消息体,所有数据承载的地方。

ErrorCode.php 是存放状态码的文件,我们在包含了这个文件后,可以通过 ErrorCode::Success 来访问我们定义状态码。

Sender.php 是一个发送文件,和发送相关的函数都会在这个文件上,内部会调用底层的网络库。

Result.php 是一个存放服务器返回结果的文件。

Constants.php 是一个存放常量和静态变量的地方。

大致上最有用的就是上面描述的文件。

小米推送实践

因为小米推送支持很多种推送方式,比如按 alias 推送, account 推送,全量推送,按标签推送(客户端订阅的方式)。这里仅仅介绍全量推送。

首先你需要在Constant类中配置好从小米平台上注册的 app 的包名和 secret

$secret = 'your app secret';
$package = 'your app packagename';

// 常量设置必须在new Sender()方法之前调用
Constants::setPackage($package);
Constants::setSecret($secret);

如果有多个应用,你可以在一个新的 config 类中存放好配置信息。

然后开始构建消息体。

$message = new Builder();
$message->title($title);
$message->description($desc);
$message->notifyType(1);
$message->passThrough($passThrough);
$message->payload($payload);
$message->extra(Builder::notifyEffect, 1);
$message->notifyId(1);
$message->timeToSend($timeToSend);
$message->build();

然后你可以设置创建一个发送类,并调用全量推送的接口。

$sender = new Sender();
$res = $sender->broadcastAll($message);
print_r($res->getRaw());                  // 查看返回的数据

你看,是不是很简单,轻轻松松实现小米推送,仅需要10分钟左右的时间,但是一定要注意返回值得错误检查。不要让程序崩了,也不要让程序返回一些人类很难看懂的字符和错误码,养成良好的编程习惯,有助于提高开发效率。

返回的数组用 json_encode 函数转为 json 格式

{
    "result": "ok",
    "trace_id": "Xcm56b094851588122700z",
    "code": 0,
    "data": {
        "id": "tcm56b09485158812276t8"
    },
    "description": "成功",
    "info": "Received push messages for 1 TOPIC"
}

如果有同学在使用小米推送平台的过程遇到问题的欢迎提出来大家一起交流!

原文  https://segmentfault.com/a/1190000008209848
正文到此结束
Loading...