1. <?php
  2.  
  3. /* phpMQTT */
  4. class phpMQTT {
  5.  
  6. private $socket; /* holds the socket */
  7. private $msgid = 1; /* counter for message id */
  8. public $keepalive = 10; /* default keepalive timmer */
  9. public $timesinceping; /* host unix time, used to detect disconects */
  10. public $topics = array(); /* used to store currently subscribed topics */
  11. public $debug = false; /* should output debug messages */
  12. public $address; /* broker address */
  13. public $port; /* broker port */
  14. public $clientid; /* client id sent to brocker */
  15. public $will; /* stores the will of the client */
  16. private $username; /* stores username */
  17. private $password; /* stores password */
  18.  
  19. function __construct($address, $port, $clientid){
  20. $this->broker($address, $port, $clientid);
  21. }
  22.  
  23. /* sets the broker details */
  24. function broker($address, $port, $clientid){
  25. $this->address = $address;
  26. $this->port = $port;
  27. $this->clientid = $clientid;
  28. }
  29.  
  30. /* connects to the broker
  31. inputs: $clean: should the client send a clean session flag */
  32. function connect($clean = true, $will = NULL, $username = NULL, $password = NULL){
  33.  
  34. if($will) $this->will = $will;
  35. if($username) $this->username = $username;
  36. if($password) $this->password = $password;
  37.  
  38. $address = gethostbyname($this->address);
  39. $this->socket = fsockopen($address, $this->port, $errno, $errstr, 60);
  40.  
  41. if (!$this->socket ) {
  42. error_log("fsockopen() $errno, $errstr \n");
  43. return false;
  44. }
  45.  
  46. stream_set_timeout($this->socket, 5);
  47. stream_set_blocking($this->socket, 0);
  48.  
  49. $i = 0;
  50. $buffer = "";
  51.  
  52. $buffer .= chr(0x00); $i++;
  53. $buffer .= chr(0x06); $i++;
  54. $buffer .= chr(0x4d); $i++;
  55. $buffer .= chr(0x51); $i++;
  56. $buffer .= chr(0x49); $i++;
  57. $buffer .= chr(0x73); $i++;
  58. $buffer .= chr(0x64); $i++;
  59. $buffer .= chr(0x70); $i++;
  60. $buffer .= chr(0x03); $i++;
  61.  
  62. //No Will
  63. $var = 0;
  64. if($clean) $var+=2;
  65.  
  66. //Add will info to header
  67. if($this->will != NULL){
  68. $var += 4; // Set will flag
  69. $var += ($this->will['qos'] << 3); //Set will qos
  70. if($this->will['retain']) $var += 32; //Set will retain
  71. }
  72.  
  73. if($this->username != NULL) $var += 128; //Add username to header
  74. if($this->password != NULL) $var += 64; //Add password to header
  75.  
  76. $buffer .= chr($var); $i++;
  77.  
  78. //Keep alive
  79. $buffer .= chr($this->keepalive >> 8); $i++;
  80. $buffer .= chr($this->keepalive & 0xff); $i++;
  81.  
  82. $buffer .= $this->strwritestring($this->clientid,$i);
  83.  
  84. //Adding will to payload
  85. if($this->will != NULL){
  86. $buffer .= $this->strwritestring($this->will['topic'],$i);
  87. $buffer .= $this->strwritestring($this->will['content'],$i);
  88. }
  89.  
  90. if($this->username) $buffer .= $this->strwritestring($this->username,$i);
  91. if($this->password) $buffer .= $this->strwritestring($this->password,$i);
  92.  
  93. $head = " ";
  94. $head{0} = chr(0x10);
  95. $head{1} = chr($i);
  96.  
  97. fwrite($this->socket, $head, 2);
  98. fwrite($this->socket, $buffer);
  99.  
  100. $string = $this->read(4);
  101.  
  102. if(ord($string{0})>>4 == 2 && $string{3} == chr(0)){
  103. if($this->debug) echo "Connected to Broker\n";
  104. }else{
  105. error_log(sprintf("Connection failed! (Error: 0x%02x 0x%02x)\n",
  106. ord($string{0}),ord($string{3})));
  107. return false;
  108. }
  109.  
  110. $this->timesinceping = time();
  111.  
  112. return true;
  113. }
  114.  
  115. /* read: reads in so many bytes */
  116. function read($int = 8192, $nb = false){
  117.  
  118. // print_r(socket_get_status($this->socket));
  119.  
  120. $string="";
  121. $togo = $int;
  122.  
  123. if($nb){
  124. return fread($this->socket, $togo);
  125. }
  126.  
  127. while (!feof($this->socket) && $togo>0) {
  128. $fread = fread($this->socket, $togo);
  129. $string .= $fread;
  130. $togo = $int - strlen($string);
  131. }
  132.  
  133. return $string;
  134. }
  135.  
  136. /* subscribe: subscribes to topics */
  137. function subscribe($topics, $qos = 0){
  138. $i = 0;
  139. $buffer = "";
  140. $id = $this->msgid;
  141. $buffer .= chr($id >> 8); $i++;
  142. $buffer .= chr($id % 256); $i++;
  143.  
  144. foreach($topics as $key => $topic){
  145. $buffer .= $this->strwritestring($key,$i);
  146. $buffer .= chr($topic["qos"]); $i++;
  147. $this->topics[$key] = $topic;
  148. }
  149.  
  150. $cmd = 0x80;
  151. //$qos
  152. $cmd += ($qos << 1);
  153.  
  154. $head = chr($cmd);
  155. $head .= chr($i);
  156.  
  157. fwrite($this->socket, $head, 2);
  158. fwrite($this->socket, $buffer, $i);
  159. $string = $this->read(2);
  160.  
  161. $bytes = ord(substr($string,1,1));
  162. $string = $this->read($bytes);
  163. }
  164.  
  165. /* ping: sends a keep alive ping */
  166. function ping(){
  167. $head = " ";
  168. $head = chr(0xc0);
  169. $head .= chr(0x00);
  170. fwrite($this->socket, $head, 2);
  171. if($this->debug) echo "ping sent\n";
  172. }
  173.  
  174. /* disconnect: sends a proper disconect cmd */
  175. function disconnect(){
  176. $head = " ";
  177. $head{0} = chr(0xe0);
  178. $head{1} = chr(0x00);
  179. fwrite($this->socket, $head, 2);
  180. }
  181.  
  182. /* close: sends a proper disconect, then closes the socket */
  183. function close(){
  184. $this->disconnect();
  185. fclose($this->socket);
  186. }
  187.  
  188. /* publish: publishes $content on a $topic */
  189. function publish($topic, $content, $qos = 0, $retain = 0){
  190.  
  191. $i = 0;
  192. $buffer = "";
  193.  
  194. $buffer .= $this->strwritestring($topic,$i);
  195.  
  196. //$buffer .= $this->strwritestring($content,$i);
  197.  
  198. if($qos){
  199. $id = $this->msgid++;
  200. $buffer .= chr($id >> 8); $i++;
  201. $buffer .= chr($id % 256); $i++;
  202. }
  203.  
  204. $buffer .= $content;
  205. $i+=strlen($content);
  206.  
  207. $head = " ";
  208. $cmd = 0x30;
  209. if($qos) $cmd += $qos << 1;
  210. if($retain) $cmd += 1;
  211.  
  212. $head{0} = chr($cmd);
  213. $head .= $this->setmsglength($i);
  214.  
  215. fwrite($this->socket, $head, strlen($head));
  216. fwrite($this->socket, $buffer, $i);
  217.  
  218. }
  219.  
  220. /* message: processes a recieved topic */
  221. function message($msg){
  222. $tlen = (ord($msg{0})<<8) + ord($msg{1});
  223. $topic = substr($msg,2,$tlen);
  224. $msg = substr($msg,($tlen+2));
  225. $found = 0;
  226. foreach($this->topics as $key=>$top){
  227. if( preg_match("/^".str_replace("#",".*",
  228. str_replace("+","[^\/]*",
  229. str_replace("/","\/",
  230. str_replace("$",'\$',
  231. $key))))."$/",$topic) ){
  232. if(function_exists($top['function'])){
  233. call_user_func($top['function'],$topic,$msg);
  234. $found = 1;
  235. }
  236. }
  237. }
  238.  
  239. if($this->debug && !$found) echo "msg recieved but no match in subscriptions\n";
  240. }
  241.  
  242. /* proc: the processing loop for an "allways on" client
  243. set true when you are doing other stuff in the loop good for watching something else at the same time */
  244. function proc( $loop = true){
  245.  
  246. if(1){
  247. $sockets = array($this->socket);
  248. $w = $e = NULL;
  249. $cmd = 0;
  250.  
  251. //$byte = fgetc($this->socket);
  252. if(feof($this->socket)){
  253. if($this->debug) echo "eof receive going to reconnect for good measure\n";
  254. fclose($this->socket);
  255. $this->connect(false);
  256. if(count($this->topics))
  257. $this->subscribe($this->topics);
  258. }
  259.  
  260. $byte = $this->read(1, true);
  261.  
  262. if(!strlen($byte)){
  263. if($loop){
  264. usleep(100000);
  265. }
  266.  
  267. }else{
  268.  
  269. $cmd = (int)(ord($byte)/16);
  270. if($this->debug) echo "Recevid: $cmd\n";
  271.  
  272. $multiplier = 1;
  273. $value = 0;
  274. do{
  275. $digit = ord($this->read(1));
  276. $value += ($digit & 127) * $multiplier;
  277. $multiplier *= 128;
  278. }while (($digit & 128) != 0);
  279.  
  280. if($this->debug) echo "Fetching: $value\n";
  281.  
  282. if($value)
  283. $string = $this->read($value,"fetch");
  284.  
  285. if($cmd){
  286. switch($cmd){
  287. case 3:
  288. $this->message($string);
  289. break;
  290. }
  291.  
  292. $this->timesinceping = time();
  293. }
  294. }
  295.  
  296. if($this->timesinceping < (time() - $this->keepalive )){
  297. if($this->debug) echo "not found something so ping\n";
  298. $this->ping();
  299. }
  300.  
  301. if($this->timesinceping<(time()-($this->keepalive*2))){
  302. if($this->debug) echo "not seen a package in a while, disconnecting\n";
  303. fclose($this->socket);
  304. $this->connect(false);
  305. if(count($this->topics))
  306. $this->subscribe($this->topics);
  307. }
  308.  
  309. }
  310. return 1;
  311. }
  312.  
  313. /* getmsglength: */
  314. function getmsglength(&$msg, &$i){
  315.  
  316. $multiplier = 1;
  317. $value = 0 ;
  318. do{
  319. $digit = ord($msg{$i});
  320. $value += ($digit & 127) * $multiplier;
  321. $multiplier *= 128;
  322. $i++;
  323. }while (($digit & 128) != 0);
  324.  
  325. return $value;
  326. }
  327.  
  328. /* setmsglength: */
  329. function setmsglength($len){
  330. $string = "";
  331. do{
  332. $digit = $len % 128;
  333. $len = $len >> 7;
  334. // if there are more digits to encode, set the top bit of this digit
  335. if ( $len > 0 )
  336. $digit = ($digit | 0x80);
  337. $string .= chr($digit);
  338. }while ( $len > 0 );
  339. return $string;
  340. }
  341.  
  342. /* strwritestring: writes a string to a buffer */
  343. function strwritestring($str, &$i){
  344. $ret = " ";
  345. $len = strlen($str);
  346. $msb = $len >> 8;
  347. $lsb = $len % 256;
  348. $ret = chr($msb);
  349. $ret .= chr($lsb);
  350. $ret .= $str;
  351. $i += ($len+2);
  352. return $ret;
  353. }
  354.  
  355. function printstr($string){
  356. $strlen = strlen($string);
  357. for($j=0;$j<$strlen;$j++){
  358. $num = ord($string{$j});
  359. if($num > 31)
  360. $chr = $string{$j}; else $chr = " ";
  361. printf("%4d: %08b : 0x%02x : %s \n",$j,$num,$num,$chr);
  362. }
  363. }
  364. }
  365.  
  366. ?>

publish.php

  1. <?php
  2.  
  3. require("./phpMQTT.php");
  4.  
  5. $mqtt = new phpMQTT("localhost", 1883, "hacker");
  6.  
  7. if ($mqtt->connect()) {
  8. $mqtt->publish("hello","Hello World! at ".date("r"),0);
  9. $mqtt->close();
  10. }
  11.  
  12. ?>

subscribe.php

  1. <?php
  2.  
  3. require("./phpMQTT.php");
  4.  
  5. $mqtt = new phpMQTT("localhost", 1883, "musikar");
  6.  
  7. if(!$mqtt->connect()){
  8. exit(1);
  9. }
  10.  
  11. $topics['hello'] = array("qos"=>0, "function"=>"procmsg");
  12. $mqtt->subscribe($topics,0);
  13.  
  14. while($mqtt->proc()){
  15.  
  16. }
  17.  
  18. $mqtt->close();
  19.  
  20. function procmsg($topic,$msg){
  21. echo "Msg Recieved: ".date("r")."\nTopic:{$topic}\n$msg\n";
  22. }
  23.  
  24. ?>

php mqtt client的更多相关文章

  1. M2Mqtt is a MQTT client available for all .Net platform

    Introduction M2Mqtt is a MQTT client available for all .Net platform (.Net Framework, .Net Compact F ...

  2. python mqtt client publish操作

    使用Python库paho.mqtt.client 模拟mqtt client 连接broker,publish topic. #-*-coding:utf-8-*- import paho.mqtt ...

  3. mqtt client python example

    This is a simple example showing how to use the [Paho MQTT Python client](https://eclipse.org/paho/c ...

  4. go ---MQTT client

    Paho GO Client   语言 GO 协议 EPL AND EDL 官网地址 http://www.eclipse.org/paho/ API类型 Asynchronous  描述 Paho ...

  5. mqtt client api: 阻塞API

    fusesource版本:mqtt-client-1.11.jar下载地址:https://github.com/fusesource/mqtt-client fusesource提供三种mqtt c ...

  6. MQTT Client library for C (MQTT客户端C语言库-paho)

    原文:http://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/index.html 来自我的CSDN博客   最近在使用Paho的MQTT客 ...

  7. MQTT Server搭建(apache-apollo)和MQtt Client搭建

    目标 本文就MQTT server和client搭建做以下总结,方便测试及开发使用,能基于MQTT软件发送和接收消息. 介绍 MQTT是基于tcp的消息发送,目前JAVA方面有两种实现,分别是mqtt ...

  8. Asynchronous MQTT client library for C (MQTT异步客户端C语言库-paho)

    原文:http://www.eclipse.org/paho/files/mqttdoc/MQTTAsync/html/index.html MQTT异步客户端C语言库   用于C的异步 MQTT 客 ...

  9. 一套权威的 MQTT Client 库

    主流的语言都支持,可链接到 github ,亲测golang client 简单好用 http://www.eclipse.org/paho/downloads.php

随机推荐

  1. 《挑战30天C++入门极限》入门教程:实例详解C++友元

        入门教程:实例详解C++友元 在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点: 通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为pu ...

  2. YII框架的模块化技术

    一.模块的创建 利用yii的自动生成工具gii生成模块. 1.访问:lcoalhost/web/index.php?r=gii 2.点击 Module Generator 下面的 start 3.填写 ...

  3. Software Project Management_JUnit && Maven

    Task1: Develop the project “HelloWorld” -A .java program: Just print out “Hello” + your name; -A tes ...

  4. Perl深度优先迷宫算法

    迷宫求解,可以用穷举法,将每个点的方向都穷举完:由于在求解过程中会遇到某一方向不可通过,此时就必须按原路返回. 想到用Perl数组来保存路径,记录每次所探索的方向,方便原路返回时得到上一步的方向,再退 ...

  5. ActiveMq 本地安装及启动(Windows)

    首先下载MQ的安装包 http://activemq.apache.org/download.html 1.点击最新版本的ActiveMQ的 2.这里有窗户版本和Linux的的版本,这里我们选择窗口版 ...

  6. (基因功能 & 基因表达调控)研究方案

    做了好久的RNA-seq分析,基因表达也在口头溜了几年了,但似乎老是浮在表面. 对一件事的了解程度决定了你的思维深度,只想做技工就不用想太多,想做大师就一定要刨根问底. 老是说基因表达,那么什么是基因 ...

  7. .gitignore忽略多层文件夹用**

    一.写法 **/bin/Debug/ 前面的两个*号代表任意多层上级文件夹 需要 git 1.8.2 及其以上的版本才支持 如何查看当前版本并且升级(windows) 二.如何升级 git是2.14. ...

  8. vim 显示行号 临时&永久

    设置vim 永久显示行号 - electrocrazy的博客 - CSDN博客https://blog.csdn.net/electrocrazy/article/details/79035216 v ...

  9. 使用hwclock读取rtc中的时间时报错"hwclock: ioctl(RTC_RD_TIME) to /dev/rtc0 to read the time failed: No such device or address"如何处理?

    1. No such device or address 这一句表明当前的板子上没有这样的外设,检查设备树和硬件连接情况 2. 笔者是这样解决的 由于设备树中为rtc所指定的总线与硬件上的连接rtc的 ...

  10. linux服务之dns

    安装dig工具 [root@cu-app-107 ~]# cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core) [root@cu-ap ...