开发者社区> 问答> 正文

PHP 收发消息如何实现?


运行环境准备
用 HTTP 协议发送或者接收消息,请完成以下准备工作。
Windows

  1. 从 IntelliJ 官网下载并安装 phpStorm 试用版:http://www.jetbrains.com/phpstorm/download/index.html
  2. 安装完毕之后,打开 phpStorm 开发环境。

其他 IDE 开发环境安装步骤与此类似。
Linux/Unix

  1. 从官网上下载 phpStorm 的 Linux 版本:http://www.jetbrains.com/phpstorm/download/index.html

  2. 解压下载成功的 phpStorm 安装包: tar xfz PhpStorm-2016.1.tar.gz

  3. 进入 phpStorm 的 bin 目录并执行安装脚本: cd phpStorm-2016.1;./phpStorm.sh

  4. 在输入注册码页面直接单击试用版。

  5. 单击确定直到出现安装完成界面。

运行示例代码
在Windows/Linux/Unix环境下,请按照以下步骤运行示例代码。

  1. 在 phpStorm 中创建 PHP 工程(工程名无特殊要求)。

  2. 将下文具体示例程序中所提供的配置文件(config.ini)以及示例程序(httpProducer.php, httpConsumer.php, Util.php)拷贝到当前的工程中,如图:

  3. 根据示例代码里的说明修改相关配置信息。

  4. 右键点击创建的 PHP 文件,选择 Run 执行。
    注意:请先执行 httpProducer.php 代码,再执行 httpConsumer.php 代码。

  5. 观察执行结果,如果执行结果有问题,请检查 config.ini 配置是否正确。

具体示例程序
以下是配置文件(config.ini)、发送消息(httpProducer.php)和接收消息(httpConsumer.php)以及所用工具方法(Util.php)的示例代码。
1. 配置文件
您需要设置配置文件(config.ini)的相关内容,具体请参考 申请 MQ 资源
  1. #您在控制台创建的Topic
  2. Topic = "xxx"
  3. #公测环境的URL
  4. URL = "http://publictest-rest.ons.aliyun.com"
  5. #阿里云身份验证码
  6. Ak = "xxx"
  7. #阿里云身份验证密钥
  8. Sk = "xxx"
  9. #MQ控制台创建的Producer ID
  10. ProducerID = "xxx"
  11. #MQ控制台创建的Consumer ID
  12. ConsumerID = "xxx"

说明: URL 中的 Key,Tag 以及 POST Content-Type 没有任何的限制,只要确保 Key 和 Tag 相同唯一即可,可以放在 user.properties 里面。
2. 发送消息示例程序(httpProducer.php)
通过 HTTP 协议发送消息,请参考以下示例代码。
  1. <?php
  2. //包含工具类
  3. include("Util.php");
  4. /*
  5. * 消息发布者者
  6. */
  7. class HttpProducer
  8. {
  9.     //签名
  10.     private static $signature = "Signature";
  11.     //在MQ控制台创建的Producer ID
  12.     private static $producerid = "ProducerID";
  13.     //阿里云身份验证码
  14.        private static $aks = "AccessKey";
  15.     //配置信息
  16.        private static $configs = null;
  17.     //构造函数
  18.     function __construct()
  19.     {
  20.             //读取配置信息
  21.             $this::$configs = parse_ini_file("config.ini");
  22.        }
  23.     //计算md5
  24.     private function md5($str)
  25.     {
  26.         return md5($str);
  27.     }
  28.     //发布消息流程
  29.     public function process()
  30.     {
  31.         //打印配置信息
  32.         var_dump($this::$configs);
  33.         //获取Topic
  34.         $topic = $this::$configs["Topic"];
  35.         //获取保存Topic的URL路径
  36.         $url = $this::$configs["URL"];
  37.         //读取阿里云访问码
  38.         $ak = $this::$configs["Ak"];
  39.         //读取阿里云密钥
  40.         $sk = $this::$configs["Sk"];
  41.         //读取Producer ID
  42.         $pid = $this::$configs["ProducerID"];
  43.         //HTTP请求体内容
  44.         $body = "This is a simple php message";
  45.         $newline = "\n";
  46.         //构造工具对象
  47.         $util = new Util();
  48.         for ($i = 0; $i<500; $i++) {
  49.             //计算时间戳
  50.             $date = time()*1000;
  51.             //POST请求url
  52.             $postUrl = $url."/message/?topic=".$topic."&time=".$date."&tag=http&key=http";
  53.             //签名字符串
  54.             $signString = $topic.$newline.$pid.$newline.$this->md5($body).$newline.$date;
  55.             //计算签名
  56.             $sign = $util->calSignature($signString,$sk);
  57.             //初始化网络通信模块
  58.             $ch = curl_init();
  59.             //构造签名标记
  60.             $signFlag = $this::$signature.":".$sign;
  61.             //构造密钥标记
  62.             $akFlag = $this::$aks.":".$ak;
  63.             //标记
  64.             $producerFlag = $this::$producerid.":".$pid;
  65.             //构造HTTP请求头部内容类型标记
  66.             $contentFlag = "Content-Type:text/html;charset=UTF-8";
  67.             //构造HTTP请求头部
  68.             $headers = array(
  69.                 $signFlag,
  70.                 $akFlag,
  71.                 $producerFlag,
  72.                 $contentFlag,
  73.             );
  74.             //设置HTTP头部内容
  75.             curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
  76.             //设置HTTP请求类型,此处为POST
  77.             curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"POST");
  78.             //设置HTTP请求的URL
  79.                curl_setopt($ch,CURLOPT_URL,$postUrl);
  80.             //设置HTTP请求的body
  81.             curl_setopt($ch,CURLOPT_POSTFIELDS,$body);
  82.               //构造执行环境
  83.               ob_start();
  84.               //开始发送HTTP请求
  85.               curl_exec($ch);
  86.               //获取请求应答消息
  87.               $result = ob_get_contents();
  88.               //清理执行环境
  89.               ob_end_clean();
  90.             //打印请求应答结果
  91.             var_dump($result);
  92.             //关闭连接
  93.             curl_close($ch);
  94.         }
  95.     }
  96. }
  97. //构造消息发布者
  98. $producer = new HttpProducer();
  99. //启动消息发布者
  100. $producer->process();
  101. ?>

3. 接收消息示例程序(httpConsumer.php)
通过 HTTP 协议接收消息,请参考以下示例代码。
  1. <?php
  2. include ("Util.php");
  3. /*
  4. * 消息订阅者
  5. */
  6. class HttpConsumer
  7. {
  8.     //签名
  9.     private static $signature = "Signature";
  10.     //Consumer ID
  11.     private static $consumerid = "ConsumerID";
  12.     //访问码
  13.     private static $ak = "AccessKey";
  14.     //配置信息
  15.     private static $config = null;
  16.     //构造函数
  17.     function __construct()
  18.     {
  19.         //读取配置信息
  20.         $this::$config = parse_ini_file("config.ini");
  21.     }
  22.     //订阅流程
  23.     public function process()
  24.     {
  25.     //打印配置信息
  26.     var_dump($this::$config);
  27.     //获取Topic
  28.     $topic = $this::$config["Topic"];
  29.     //获取Topic的URL路径
  30.     $url = $this::$config["URL"];
  31.     //阿里云身份验证码
  32.     $ak = $this::$config["Ak"];
  33.     //阿里云身份验证密钥
  34.     $sk = $this::$config["Sk"];
  35.     //Consumer ID
  36.     $cid = $this::$config["ConsumerID"];
  37.     $newline = "\n";
  38.     //构造工具对象
  39.     $util = new Util();
  40.     while (true)
  41.     {
  42.         try
  43.         {
  44.             //构造时间戳
  45.             $date = time()*1000;
  46.             //签名字符串
  47.             $signString = $topic.$newline.$cid.$newline.$date;
  48.             //计算签名
  49.             $sign = $util->calSignature($signString,$sk);
  50.             //构造签名标记
  51.             $signFlag = $this::$signature.":".$sign;
  52.             //构造密钥标记
  53.             $akFlag = $this::$ak.":".$ak;
  54.             //标记
  55.             $consumerFlag = $this::$consumerid.":".$cid;
  56.             //构造HTTP请求发送内容类型标记
  57.             $contentFlag = "Content-Type:text/html;charset=UTF-8";
  58.             //构造HTTP头部信息
  59.             $headers = array(
  60.                 $signFlag,
  61.                 $akFlag,
  62.                 $consumerFlag,
  63.                 $contentFlag,
  64.             );
  65.             //构造HTTP请求URL
  66.             $getUrl = $url."/message/?topic=".$topic."&time=".$date."&num=32";
  67.             //初始化网络通信模块
  68.             $ch = curl_init();
  69.             //填充HTTP头部信息
  70.             curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
  71.             //设置HTTP请求类型,此处为GET
  72.             curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"GET");
  73.             //设置HTTP请求URL
  74.             curl_setopt($ch,CURLOPT_URL,$getUrl);
  75.             //构造执行环境
  76.             ob_start();
  77.             //开始发送HTTP请求
  78.             curl_exec($ch);
  79.             //获取请求应答消息
  80.             $result = ob_get_contents();
  81.             //清理执行环境
  82.             ob_end_clean();
  83.             //打印请求应答信息
  84.             var_dump($result);
  85.             //关闭HTTP网络连接
  86.             curl_close($ch);
  87.             //解析HTTP应答信息
  88.             $messages = json_decode($result,true);
  89.             //如果应答信息中的没有包含任何的Topic信息,则直接跳过
  90.             if (count($messages) ==0)
  91.             {
  92.                 continue;
  93.             }
  94.             //依次遍历每个Topic消息
  95.             foreach ((array)$messages as $message)
  96.             {
  97.                 var_dump($message);
  98.                 //获取时间戳
  99.                 $date = (int)($util->microtime_float()*1000);
  100.                 //构造删除Topic消息URL
  101.                 $delUrl = $url."/message/?msgHandle=".$message['msgHandle']."&topic=".$topic."&time=".$date;
  102.                 //签名字符串
  103.                 $signString = $topic.$newline.$cid.$newline.$message['msgHandle'].$newline.$date;
  104.                 //计算签名
  105.                 $sign = $util->calSignature($signString,$sk);
  106.                 //构造签名标记
  107.                 $signFlag = $this::$signature.":".$sign;
  108.                 //构造密钥标记
  109.                 $akFlag = $this::$ak.":".$ak;
  110.                 //构造消费者组标记
  111.                 $consumerFlag = $this::$consumerid.":".$cid;
  112.                 //构造HTTP请求头部信息
  113.                 $delheaders = array(
  114.                     $signFlag,
  115.                     $akFlag,
  116.                     $consumerFlag,
  117.                     $contentFlag,
  118.                 );
  119.                 //初始化网络通信模块
  120.                 $ch = curl_init();
  121.                 //填充HTTP请求头部信息
  122.                 curl_setopt($ch,CURLOPT_HTTPHEADER,$delheaders);
  123.                 //设置HTTP请求URL信息
  124.                 curl_setopt($ch,CURLOPT_URL,$delUrl);
  125.                 //设置HTTP请求类型,此处为DELETE
  126.                 curl_setopt($ch,CURLOPT_CUSTOMREQUEST,'DELETE');
  127.                 //构造执行环境
  128.                 ob_start();
  129.                 //开始发送HTTP请求
  130.                 curl_exec($ch);
  131.                 //获取请求应答消息
  132.                 $result = ob_get_contents();
  133.                 //清理执行环境
  134.                 ob_end_clean();
  135.                 //打印应答消息
  136.                 var_dump($result);
  137.                 //关闭连接
  138.                 curl_close($ch);
  139.             }
  140.         }
  141.         catch (Exception $e)
  142.         {
  143.             //打印异常信息
  144.             echo $e->getMessage();
  145.         }
  146.     }
  147.     }
  148. }
  149. //构造消息订阅者
  150. $consumer = new HttpConsumer();
  151. //启动消息订阅者
  152. $consumer->process();        
  153. ?>

4. 工具方法(Util.php)示例程序
示例中使用的工具方法如下。
  1. <?php
  2. /*
  3. * 工具类
  4. */
  5. class Util
  6. {
  7.     //计算签名
  8.     public static function calSignature($str,$key)
  9.     {
  10.         $sign = "";
  11.         if(function_exists("hash_hmac"))
  12.         {
  13.             $sign = base64_encode(hash_hmac("sha1",$str,$key,true));
  14.         }
  15.         else
  16.         {
  17.             $blockSize = 64;
  18.             $hashfunc = "sha1";
  19.             if(strlen($key) > $blockSize)
  20.             {
  21.                 $key = pack('H*',$hashfunc($key));
  22.             }
  23.             $key = str_pad($key,$blockSize,chr(0x00));
  24.             $ipad = str_repeat(chr(0x36),$blockSize);
  25.             $opad = str_repeat(chr(0x5c),$blockSize);
  26.             $hmac = pack(
  27.                 'H*',$hashfunc(
  28.                     ($key^$opad).pack(
  29.                         'H*',$hashfunc($key^$ipad).$str
  30.                     )
  31.                 )
  32.             );
  33.             $sign = base64_encode($hmac);
  34.         }
  35.         return $sign;
  36.     }
  37.     //计算时间戳
  38.     public static function microtime_float()
  39.     {
  40.         list($usec,$sec) = explode(" ",microtime());
  41.         return ((float)$usec+(float)$sec);
  42.     }
  43. }
  44. ?>

展开
收起
猫饭先生 2017-10-27 10:17:37 2447 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
阿里云栖开发者沙龙PHP技术专场-深入浅出网络编程与swoole内核-吴镇宇 立即下载
PHP安全开发:从白帽角度做安全 立即下载
PHP 2017.北京 全球开发者大会——高可用的PHP 立即下载