服务器的搭建
搭建部分参考的https://blog.csdn.net/pjlxm/article/details/78539984此文章
1,首先下载一个apollo,作用是通过此方法来建立服务器,具体流程如下
1.下载Apolllo,然后解压到一个目录,进入dos窗口(cmd命令行窗口)切换到Apollo的目录,进入bin目录,然后运行“apollo.cmd create zza”
创建服务器实例。
2.创建实例之后会在bin目录下生成zza文件夹,cd进zza目录:
etc目录下的apollo.xml文件下是配置服务器信息的文件,users.properties文件包含了连接MQTT服务器时用到的用户名和密码(需要谨记),初始默认帐号是admin,密码password;
3.把MQTT服务作为windows服务(install),然后进行启动(start);
启动的代码是:apollo-broker.cmd run;然后就会看到吧所有连接服务器的方法地址都展示出来了
4,下载一个工具,这里是推荐的一个eclipse工具(eclipse-paho MQTT),然后新建一个mqtt的连接输入服务器展示出来的地址,然后高级选项里面输入账号admin,密码password,连接成功
同时在浏览器输入本地服务器,或者127.0.0.1:61681进入服务器操作页面,然后我们可以看到已经获取到了客户端发来的消息
然后今天大体了解了一下MQTT的网络之间信息流通的基本过程,明天准备了解一下Android与MQTT之间的订阅与发布的基本操作。
别忘了添加依赖!!!!!!!!!
repositories {
maven {
url"https://repo.eclipse.org/content/repositories/paho-releases/"
}
}
dependencies {
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
}
在manifest.xml文件中配置权限
Android方向操作:
首先是最为主要的MQTTManager类
package com.example.mqtt;
导包略
public class MqttManager {
public static final String TAG = MqttManager.class.getSimpleName();
private String host;
private String username;
private String password;
private String clientId;
//创建用于连接mqtt服务器的相关内容,分别是服务器的地址
//还有就是服务器的相关密码账户,还有客户端的ID
private MqttClient client;
//创建mqttClient对象,以及连接的对象
private MqttConnectOptions connectOptions;
/**
* 三个参数的构造方法
* 以及自动获取客户端的ID
* 这就是上面的三个参数,还有一个是当时准备传入主UI线程的,后来就没用到
* @param host
* @param username
* @param password
* @param activity
*/
public MqttManager(String host, String username, String password, Activity activity){
this.host=host;
this.password=password;
this.username=username;
this.clientId= MqttClient.generateClientId();
}
/**
* 连接操作
* 首先创建一个客户端对象,同时把地址,id传进去
* 其次再把账户密码穿进去
* 输入一个callback实例
* 开始连接服务器
*/
public void connect(){
try{
client = new MqttClient(host,clientId,new MemoryPersistence());
connectOptions = new MqttConnectOptions();
connectOptions.setUserName(username);
connectOptions.setPassword(password.toCharArray());
client.setCallback(mqttCallback);
client.connect(connectOptions);
}catch (MqttException e){
e.printStackTrace();
}
}
/**
* 获取函数
* 下面两个参数主要是一个是消息对列的名称,一个是服务质量
* 然后把这两个对象装程数组类型
* 然后通过调用客户端的函数subscribe来读取消息
* @param topic
* @param qos
*/
public void subscribe(String topic,int qos){
if(client != null){
int[] Qos = {qos};
String[] topic1 = {topic};
try {
client.subscribe(topic1, Qos);
Log.d(TAG,"订阅topic : "+topic);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
/**
* 此为向服务器发布数据的操作封装函数
* 在这里的四个参数的意思分别是
* @param topic 消息队列
* @param msg 向服务器发送到消息
* @param isRetained 是否保留,一般false
* @param qos 服务质量
* 新建一个MqttMessa对象然后分别通过对应的set函数将
* 这四个参数穿进去然后调用客户端里面的publish函数进行
* 获取服务器里面的信息
* 并打印日志
*/
public void publish(String topic,String msg,boolean isRetained,int qos) {
try {
if (client!=null) {
MqttMessage message = new MqttMessage();
message.setQos(qos);
message.setRetained(isRetained);
message.setPayload(msg.getBytes());
client.publish(topic, message);
Log.i(TAG, "publish: zzzzzzzzz");
}
} catch (MqttPersistenceException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
}
}
String payload;
private MqttCallback mqttCallback = new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
Log.i(TAG,"connection lost");
}
@Override
public void messageArrived(String topic, MqttMessage message){
Log.i(TAG,"received topic : " + topic);
payload= new String(message.getPayload());
//捕获从服务器端发送过来的信息通过下面的a()函数传出去
Log.i(TAG,"received msg : " + payload);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i(TAG,"deliveryComplete");
}
};
public String a(){
//别的类读取信息调用此函数即可
return payload;
}
}
然后是main活动类
package com.example.mqtt;
导包
public class MainActivity extends AppCompatActivity {
private MqttManager mqttManager ;
private EditText editText1,editText2,editText3,editText4,editText5,editText6;
private Button button1,button2,button3;
private ListView listView;
private baseAdapter baseAdapter;
//关联相关的控件
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
id();
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//连接服务器按钮,通过用户输入的地址,,账户密码来调用连接函数
mqttManager=new MqttManager("tcp://"+editText1.getText().toString().trim(),editText2.getText().toString().trim(),editText3.getText().toString().trim(),MainActivity.this);
mqttManager.connect();
Toast.makeText(getApplicationContext(),"连接成功",Toast.LENGTH_SHORT).show();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//防止程序崩溃,在这里判断一下,用户输入的地方是否为空,不为空直接通过publish函数发送消息
if(!editText4.getText().toString().equals("")&&!editText5.getText().toString().equals("")){
mqttManager.publish(editText4.getText().toString().trim(),editText5.getText().toString(),false,0);
Toast.makeText(getApplicationContext(),"发送成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),"消息队列不能为空",Toast.LENGTH_SHORT).show();
}
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!editText6.getText().toString().equals("")){
//接收消息判断完成之后即可传入消息队列的名称即可,通过适配器来讲数据呈现在list控件上面
mqttManager.subscribe(editText6.getText().toString(),0);
if(mqttManager.a()!=null){
Toast.makeText(getApplicationContext(),"接收",Toast.LENGTH_SHORT).show();
List list =new ArrayList();
list.add(new Date("消息接收:"+mqttManager.a()));
// for (int i=0;i<20;i++){
// list.add(new Date("zza"+i));
// }
baseAdapter=new baseAdapter(MainActivity.this,list);
listView.setAdapter(baseAdapter);
}else{
Log.i("as", "onClick: asdas");
}
}else{
Toast.makeText(getApplicationContext(),"消息队列不能为空",Toast.LENGTH_SHORT).show();
}
}
});
}
private void id(){
关联控件
}
}
baseAdapter类
package com.example.mqtt;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
/**
* baseAdapter类
*/
public class baseAdapter extends BaseAdapter {
// 创建一个list对象,和一个用来加载是哪一个页面使用此适配器的LayoutInflater,并传入一个上下文对象
private List mlist;
private LayoutInflater inflater;
public baseAdapter(Context context,List list){
mlist=list;
inflater = LayoutInflater.from(context);
}
//获取list的长度
@Override
public int getCount() {
return mlist.size();
}
//获取某一个index的值
@Override
public Object getItem(int position) {
return mlist.get(position);
}
//直接返回index即可
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Find find;//创建对象,当view为空的时候创建一个新的view,不为空则直接调用即可
//大大的节省了findview的时间
if(convertView==null){
find=new Find();
convertView=inflater.inflate(R.layout.item,null);
find.textView=convertView.findViewById(R.id.textView_ad);
convertView.setTag(find);
}else{
find=(Find)convertView.getTag();
}
Date date =mlist.get(position);
find.textView.setText(date.datae);
return convertView;
}
//创建一个类,用来保存相应的控件
class Find{
public TextView textView;
}
}