(本文把服务器搭建和unity客户端代码一起讲了,文章可能会有点长,请耐心看完)
MQTT是IBM开源的一个通讯方式,如果你是在做物联网或传感器之类的通讯,这个通讯方式十分适合你,下面讲一下MQTT的优点:
再看看百度百科它的应用:
是不是很牛逼呢?
作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
再具体看看它的通讯方式结构:
解释一下:实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者.
那么,我们就明白了,如果我们需要在本地搭建一套MQTT的通讯方式,至少有两个身份,Broker(也就是服务器)和客户端,因为客户端可以同时是订阅者和发布者,服务器只是作为中转消息的作用,其实消息的真实来源是发布者。
这次我们使用unity来实现这一个过程,首先我们先建立以下服务器,服务器我们采用apache-apollo,文章最后会提供包
接着,我们来讲一下怎么搭建apache-apollo,下载后文末提供的压缩包,解压之后,在bin目录下,按住键盘shift+鼠标右键,打开命令行:输入命令apollo.cmd create mybroker
如果没有这样的画面出现或者报错,请先检测自己电脑的java环境变量是否正常,可以打开cmd命令行,输入javac查看一下,如果有相关信息,就是正确的环境
上面的命令无误执行完之后,会生成一个新的文件夹:
进入该文件夹的bin目录,再次按住shift+鼠标右键,敲击下面的命令: "apollo-broker" run,最好不要中文路径
服务器就这样启动了,我们可以在浏览器上面输入http://127.0.0.1:61680进入服务器页面,默认账号密码是 admin password
为了更好的在本机测试,我们修改一下配置文件,重新启动一下服务器,在生成的文件夹下面的etc文件夹,找到这个文件,打开:
找到下图的内容,把0.0.0.0修改为127.0.0.1,保存后重启服务器:
待会我们直接连上这个地址就行了。
接下来,轮到我们熟悉的unity了,就是我们的主场了啊,首先拷贝好相关的库文件,后面我会一起提供了,不要着急,先来看看代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
using UnityEngine;
using UnityEngine.UI;
public class MQTT_Manager : MonoBehaviour
{
[SerializeField] private InputField ip;
[SerializeField] private InputField port;
[SerializeField] private InputField subscribe_chanel;
[SerializeField] private InputField publish_chanel;
[SerializeField] private InputField publish_content;
[SerializeField] private Button connect_btn;
[SerializeField] private Button subscribe_btn;
[SerializeField] private Button publish_btn;
[SerializeField] private Text receive_Message_text;
private MqttClient client;
private string receive_message;
// Use this for initialization
void Start () {
//连接按钮监听事件
connect_btn.onClick.AddListener(() =>
{
string txtIP = ip.text;
string txtPort = port.text;
string clientId = Guid.NewGuid().ToString();
//服务器默认密码是这个
string username = "admin";
string password = "password";
client = new MqttClient(IPAddress.Parse(txtIP), int.Parse(txtPort), false, null);
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
client.MqttMsgSubscribed += Client_MqttMsgSubscribed; ;
client.Connect(clientId, username, password);
});
//订阅按钮监听事件
subscribe_btn.onClick.AddListener(() =>
{
if (client != null&&subscribe_chanel.text!="")
{
client.Subscribe(new string[] { subscribe_chanel.text }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
}
});
//发布按钮监听事件
publish_btn.onClick.AddListener(() =>
{
if (client != null && publish_chanel.text != "")
{
client.Publish(publish_chanel.text, System.Text.Encoding.UTF8.GetBytes(publish_content.text), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
}
});
}
private void Client_MqttMsgSubscribed(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgSubscribedEventArgs e)
{
Debug.Log("订阅" + e.MessageId);
}
private void Client_MqttMsgPublishReceived(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e)
{
string message=System.Text.Encoding.UTF8.GetString(e.Message);
receive_message = message;
Debug.Log("接收到消息是"+message);
}
// Update is called once per frame
void Update ()
{
receive_Message_text.text = receive_message;
}
}
再看看我的界面:
如果你想更好的理解MQTT,建议了发布一个程序出去,一个当发布者,编辑器的程序当订阅者:
如果你想收到消息,订阅的频道必须跟发布消息的一致,下面我在同一个客户端演示一下:
连接之后,再看看我们服务器后台:
连上了是吧
明白了吧,最后讲几个MQTT比较重要的点:
MQTT有三种消息发布服务质量:
具体使用哪一种,看你的使用场景,看看我们代码中是怎么调这个的,
这个是只有一次,英文的事情自己多读读哈,看看源码:
还有一个,鼠标放上去,看看这个方法:
retain:true:表示发送的消息需要一直持久保存(不受服务器重启影响),不但要发送给当前的订阅者,并且以后新来的订阅了此Topic name的订阅者会马上得到推送。
备注:新来乍到的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送。
false:仅仅为当前订阅者推送此消息。
假如服务器收到一个空消息体(zero-length payload)、RETAIN = 1、已存在Topic name的PUBLISH消息,服务器可以删除掉对应的已被持久化的PUBLISH消息。
希望对大家有用,如果你觉得我写得不错的话,你可以关注我,如果你对UE4,python和js有兴趣,也可以关注我:
本文的Unity源码的地址是https://github.com/Leemu0822/MQTT_Unity
不用github的兄弟或者你可以关注我的公众号,回复关键字"MQTT"获取源码和服务器包