go ---MQTT client
<p> </p><table border="0">
<tbody>
<tr>
<td colspan="2">Paho GO Client </td>
</tr>
<tr>
<td>语言 </td>
<td>GO</td>
</tr>
<tr>
<td>协议</td>
<td>EPL AND EDL</td>
</tr>
<tr>
<td>官网地址</td>
<td>http://www.eclipse.org/paho/</td>
</tr>
<tr>
<td>API类型</td>
<td>Asynchronous </td>
</tr>
</tbody>
</table>
<h1>描述</h1>
<p> </p>
<p>Paho GO 库包含一个可以作为独立读写MQTT的包。</p>
<p>PAho Go 库目前是0.9版本,即将释放1.0的稳定版本,由于被商业和开源项目采用(例如Gobot ),该项目被积极的维护。</p>
<h1>特性</h1>
<table border="0">
<tbody>
<tr>
<td>MQTT3.1</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
<td> </td>
<td>Qos 0</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
</tr>
<tr>
<td>MQTT3.1.1</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
<td> </td>
<td>Qos 1</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
</tr>
<tr>
<td>LWT</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
<td> </td>
<td>Q0s 2</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
</tr>
<tr>
<td>SSL/TLS</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
<td> </td>
<td>Authentication</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
</tr>
<tr>
<td>Automatic Reconnect</td>
<td><img src="https://www.hivemq.com/wp-content/uploads/ok.png"></td>
<td> </td>
<td>Throttling</td>
<td> <img src="https://www.hivemq.com/wp-content/uploads/nok_gray1.png"></td>
</tr>
</tbody>
</table>
<p><strong>使用</strong></p>
<h2>安装</h2>
<p>假设你有一个Go的开发环境,你有一个很简单的方法获取Paho Go库并运行;</p>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_34266" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go keyword bold">go</code> <code class="go plain">get git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> 如下会将库下载到你的$GOPATH/src 目录下,你就可以在你的项目下添加到你的Import列表下使用该库:</p>
<div class="cnblogs_code">
<pre>git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git</pre>
</div>
<h2>连接</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_415713" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">opts := mqtt.NewClientOptions().AddBroker(</code><code class="go string">"tcp://broker.hivemq.com:1883"</code><code class="go plain">).SetClientID(</code><code class="go string">"sample"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go spaces"> </code> </div>
<div class="line number3 index2 alt2"><code class="go plain">c := mqtt.NewClient(opts)</code></div>
<div class="line number4 index3 alt1"><code class="go keyword bold">if</code> <code class="go plain">token := c.Connect(); token.Wait() && token.Error() != nil {</code></div>
<div class="line number5 index4 alt2"><code class="go spaces"> </code><code class="go plain">panic(token.Error())</code></div>
<div class="line number6 index5 alt1"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> 为了连接到MQTT代理,你必须提供两个必要的参数:代理的URL和使用的客户端ID。为此,我们创建了一个新的ClientOptions结构体实例,该结构体包含代理的Url和客户端ID。在ClientOptions结构体上操作的方法们返回一个可更改的结构体指针,这使你可以将方法连在一块。</p>
<p> 参考了Paho Java 库,Paho Go 库允许你在完成操作时很容易的接受一个token,该token可以被用来指示操作是否完成。token.Wait()是个阻塞函数,只有在操作完成时才返回。token.WaitTimeout()会在操作完成后等待几毫秒后返回。</p>
<h2>连接到MQTT3.1或MQTT3.1.1</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_523374" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">opts := mqtt.NewClientOptions().AddBroker(</code><code class="go string">"tcp://broker.hivemq.com:1883"</code><code class="go plain">).SetClientID(</code><code class="go string">"sample"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go plain">opts.SetProtocolVersion(4)</code></div>
<div class="line number3 index2 alt2"><code class="go spaces"> </code> </div>
<div class="line number4 index3 alt1"><code class="go plain">c := mqtt.NewClient(opts)</code></div>
<div class="line number5 index4 alt2"><code class="go keyword bold">if</code> <code class="go plain">token := c.Connect(); token.Wait() && token.Error() != nil {</code></div>
<div class="line number6 index5 alt1"><code class="go spaces"> </code><code class="go plain">panic(token.Error())</code></div>
<div class="line number7 index6 alt2"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> Paho Go 库默认使用MQTT3.1.1协议连接代理,如果失败他会自动回调并使用MQTT3.1协议连接。SetProtocolVersion()方法允许你明确的设置连接协议,4是3.1.1,3是3.1。如果显示设置,那么回调机制是禁用的。</p>
<h2>使用LWT(临终遗嘱)连接</h2>
<blockquote>
<p>LWT:该协议提供了检测方式,利用KeepAlive机制在客户端异常断开时发现问题。因此当客户端电量耗尽、崩溃或者网络断开时,消息代理会采取相应措施。</p>
<p>客户端会向任意点的消息代理发送“临终遗嘱”(LWT)信息,当消息代理检测到客户端离线(连接并未关闭),就会发送保存在特定主题上的 LWT 信息,让其它客户端知道该节点已经意外离线。</p>
</blockquote>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_957737" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">opts := mqtt.NewClientOptions().AddBroker(</code><code class="go string">"tcp://broker.hivemq.com:1883"</code><code class="go plain">).SetClientID(</code><code class="go string">"sample"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go plain">opts.SetWill(</code><code class="go string">"my/will/topic"</code><code class="go plain">, </code><code class="go string">"Goodbye"</code><code class="go plain">, 1, true)</code></div>
<div class="line number3 index2 alt2"><code class="go spaces"> </code> </div>
<div class="line number4 index3 alt1"><code class="go plain">c := mqtt.NewClient(opts)</code></div>
<div class="line number5 index4 alt2"><code class="go keyword bold">if</code> <code class="go plain">token := c.Connect(); token.Wait() && token.Error() != nil {</code></div>
<div class="line number6 index5 alt1"><code class="go spaces"> </code><code class="go plain">panic(token.Error())</code></div>
<div class="line number7 index6 alt2"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> Paho Go库有两个方法设置LWT。SetWill()和SetBinaryWill(),这两个方法都有四个参数。两个方法中的第一个参数都是字符串型的LWT订阅。第二个参数是消息体(payload),在SetWill()中是一个字符创型,在SetBinaryWill()中是byte数组。第三个参数是消息的qos类型,第四个参数是LWT的是否保持连接布尔值。</p>
<h2>使用用户名/密码连接</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_701468" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">opts := mqtt.NewClientOptions().AddBroker(</code><code class="go string">"tcp://broker.hivemq.com:1883"</code><code class="go plain">).SetClientID(</code><code class="go string">"sample"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go plain">opts.SetUsername(</code><code class="go string">"username"</code><code class="go plain">)</code></div>
<div class="line number3 index2 alt2"><code class="go plain">opts.SetPassword(</code><code class="go string">"password"</code><code class="go plain">)</code></div>
<div class="line number4 index3 alt1"><code class="go spaces"> </code> </div>
<div class="line number5 index4 alt2"><code class="go plain">c := mqtt.NewClient(opts)</code></div>
<div class="line number6 index5 alt1"><code class="go keyword bold">if</code> <code class="go plain">token := c.Connect(); token.Wait() && token.Error() != nil {</code></div>
<div class="line number7 index6 alt2"><code class="go spaces"> </code><code class="go plain">panic(token.Error())</code></div>
<div class="line number8 index7 alt1"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<h2>发布</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_378480" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">c.Publish(</code><code class="go string">"test/topic"</code><code class="go plain">, 1, false, </code><code class="go string">"Example Payload"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go spaces"> </code> </div>
<div class="line number3 index2 alt2"><code class="go keyword bold">if</code> <code class="go plain">token := c.Publish(</code><code class="go string">"test/topic"</code><code class="go plain">, 1, false, </code><code class="go string">"Example Payload"</code><code class="go plain">); token.Wait() && token.Error() != nil {</code></div>
<div class="line number4 index3 alt1"><code class="go spaces"> </code><code class="go plain">fmt.Println(token.Error())</code></div>
<div class="line number5 index4 alt2"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> 上述中,c是mqtt.NewClient()返回的mqtt.Client。发布 使用4个参数;发布消息的字符串型的topic,消息的qos质量,是否保持消息连接的bool,或者既可以是字符串形式也可以是byte数组的消息体(payload)。并且我示范了如何使用和不适用token进行消息发布。</p>
<h2>发布保留连接信息</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_755857" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">c.Publish(</code><code class="go string">"test/topic"</code><code class="go plain">, 1, true, </code><code class="go string">"Example Payload"</code><code class="go plain">)</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<h2>订阅</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_311410" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go keyword bold">var</code> <code class="go plain">msgRcvd := </code><code class="go keyword bold">func</code><code class="go plain">(client *mqtt.Client, message mqtt.Message) {</code></div>
<div class="line number2 index1 alt1"><code class="go spaces"> </code><code class="go plain">fmt.Printf(</code><code class="go string">"Received message on topic: %s\nMessage: %s\n"</code><code class="go plain">, message.Topic(), message.Payload())</code></div>
<div class="line number3 index2 alt2"><code class="go plain">}</code></div>
<div class="line number4 index3 alt1"><code class="go spaces"> </code> </div>
<div class="line number5 index4 alt2"><code class="go keyword bold">if</code> <code class="go plain">token := c.Subscribe(</code><code class="go string">"example/topic"</code><code class="go plain">, 0, msgRcvd); token.Wait() && token.Error() != nil {</code></div>
<div class="line number6 index5 alt1"><code class="go spaces"> </code><code class="go plain">fmt.Println(token.Error())</code></div>
<div class="line number7 index6 alt2"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> Subscribe()使用3个参数,一个订阅的字符串形式的topic,订阅的qos质量和一个在接受到匹配订阅消息时的函数回调。回调函数必须有一个func(*mqtt.Client,mqtt.Message)的结构。当回调函数为空(nil)的时候,在库接受到消息后会调用客户端的默认消息处理程序(如果设置)。可以在结构体ClientOptions的SetDefaultPublishHandler()中设置。</p>
<h2>取消订阅</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_321609" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">c.Unsubscribe(</code><code class="go string">"example/topic"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go spaces"> </code> </div>
<div class="line number3 index2 alt2"><code class="go keyword bold">if</code> <code class="go plain">token := c.Unsubscribe(</code><code class="go string">"example/topic"</code><code class="go plain">); token.Wait() && token.Error() != nil {</code></div>
<div class="line number4 index3 alt1"><code class="go spaces"> </code><code class="go plain">fmt.Println(token.Error())</code></div>
<div class="line number5 index4 alt2"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> Unsubscribe()可以接受多于一个的取消订阅的topic的参数,每个topic使用单独的字符串型数组参数分开。</p>
<h2>断开连接</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_881747" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">c.Disconnect(250)</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> Disconnect()使用一个参数,该参数为线程中结束任何工作的毫秒数。</p>
<h2>使用SSL/TLS</h2>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_720369" class="syntaxhighlightergo">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="go plain">opts := mqtt.NewClientOptions().AddBroker(</code><code class="go string">"ssl://iot.eclipse.org:8883"</code><code class="go plain">).SetClientID(</code><code class="go string">"sample"</code><code class="go plain">)</code></div>
<div class="line number2 index1 alt1"><code class="go spaces"> </code> </div>
<div class="line number3 index2 alt2"><code class="go plain">c := mqtt.NewClient(opts)</code></div>
<div class="line number4 index3 alt1"><code class="go keyword bold">if</code> <code class="go plain">token := c.Connect(); token.Wait() && token.Error() != nil {</code></div>
<div class="line number5 index4 alt2"><code class="go spaces"> </code><code class="go plain">panic(token.Error())</code></div>
<div class="line number6 index5 alt1"><code class="go plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> 你可以非常简单的通过改变代理URL来连接到具有SSL/TLS的代理;ssl,tls或者tcps都被client支持并且安全的连接。此处假设你连接的是使用系统已知证书的代理。如果你使用自我签名的证书你需要使用 TLS。使用ClientOptions的SetTlSConfig()配置。Paho Go库的Sample文件夹中有此示例代码。</p><br><br>
来源:https://www.cnblogs.com/saryli/p/11654665.html
頁:
[1]