RabbitMQ的Android端接收
来源:互联网 发布:二胡自学 知乎 编辑:程序博客网 时间:2024/05/21 10:48
RabbitMQ的Android端接收
版权声明:本文为博主原创文章,未经博主允许不得转载。
本次做的项目,有一部分是通过RabbitMQ来传输的实时数据。然后我这Android端就需要研究怎么接收。以前用的volley什么的,都是用http通讯的,这个稍微不太一样,采用的消息队列的方式,生产者与消费者的设计模式,观察者模式。有次面试就挂这了TT。
看了下RabbitMQ,可以服务端上可以设置为
工作队列(Work queues)这种模式下,只有一个消息队列,但是有多个消费者,这样每个任务只会被一个消费者处理
订阅发布模式(Publish/Subscribe)这种模式下,会有多个队列,每个队列都有一个消费者
我们项目中服务端应该用的就是Publish/Subscribe这种。
从官网盗图
除了生产者、消费者、消息队列这些东西外,还多了一个X,这个X指的是Exchanges(可以翻译成交换机)。
在这种模式下,生产者不直接把信息发送给消息队列,而是只发送给Exchanges,由Exchanges转发给每个消息队列。
Exchanges收到信息后会进行一些处理,比如这个消息我都应该发送给哪些队列,还是只发送给一个队列,还是应该丢弃这个消息。这样每个消息队列从Exchanges收到的东西可能都不一样,收到的消息都是根据每个消息队列的需求定制的。比如我们项目分为了油车和电车两种,可以有两个消息队列,一个消息队列只收油车数据,一个只收电车数据。这样根据需要,我在客户端这可以指定我只接受电车的数据了,我就可以从只收电车数据的这个消息队列里取了。
然后开始实现:
https://www.cloudamqp.com/blog/2015-07-29-rabbitmq-on-android.html
在这发现了一篇好教程,直接教我怎么在Android上实现。
代码不多,很容易就可以实现。
我把代码精简了下,因为我这只需要从服务器接收数据就可以了,所以把publish的代码删了
主要流程如下:
- 设置连接参数setupConnectionFactory
- 创建一个用于从线程中接收数据来更新UI的handler
- 启动一个订阅者线程,创建一个队列,将其bind到参数中指定的Exchanges上,并根据传入的routingKey路由关键字来从Exchanges中接收指定类型的消息数据。
- 之后创建消费者consumer从消息队列中循环请求数据。
package edu.hrbeu.ice.rabbitmqclient;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.QueueingConsumer;import java.net.URISyntaxException;import java.security.KeyManagementException;import java.security.NoSuchAlgorithmException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.BlockingDeque;import java.util.concurrent.LinkedBlockingDeque;public class MainActivity extends AppCompatActivity { ConnectionFactory factory = new ConnectionFactory(); Thread subscribeThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //连接设置 setupConnectionFactory(); //用于从线程中获取数据,更新ui final Handler incomingMessageHandler = new Handler() { @Override public void handleMessage(Message msg) { String message = msg.getData().getString("msg"); TextView tv = (TextView) findViewById(R.id.textView); Date now = new Date(); SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss"); tv.append(ft.format(now) + ' ' + message + '\n'); Log.i("test", "msg:" + message); } }; //开启消费者线程 subscribe(incomingMessageHandler); } /** * 连接设置 */ private void setupConnectionFactory() { factory.setHost("server url"); factory.setPort(5671); factory.setUsername("guest"); factory.setPassword("guest"); } /** * 消费者线程 */ void subscribe(final Handler handler) { subscribeThread = new Thread(new Runnable() { @Override public void run() { while (true) { try { //使用之前的设置,建立连接 Connection connection = factory.newConnection(); //创建一个通道 Channel channel = connection.createChannel(); //一次只发送一个,处理完成一个再获取下一个 channel.basicQos(1); AMQP.Queue.DeclareOk q = channel.queueDeclare(); //将队列绑定到消息交换机exchange上 // queue exchange routingKey路由关键字,exchange根据这个关键字进行消息投递。 channel.queueBind(q.getQueue(), "amq.fanout", "chat"); //创建消费者 QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(q.getQueue(), true, consumer); while (true) { //wait for the next message delivery and return it. QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); Log.d("", "[r] " + message); //从message池中获取msg对象更高效 Message msg = handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putString("msg", message); msg.setData(bundle); handler.sendMessage(msg); } } catch (InterruptedException e) { break; } catch (Exception e1) { Log.d("", "Connection broken: " + e1.getClass().getName()); try { Thread.sleep(5000); //sleep and then try again } catch (InterruptedException e) { break; } } } } }); subscribeThread.start(); } @Override protected void onDestroy() { super.onDestroy(); subscribeThread.interrupt(); }}
源码地址
- RabbitMQ的Android端接收
- RabbitMQ的Android端接收
- Android文件上传,PHP端接收
- Android文件上传,PHP端接收
- Android文件上传 PHP端接收
- Android文件上传,PHP端接收
- Android文件上传,PHP端接收
- Android文件上传,PHP端接收
- rabbitmq四---通过路由规则,接收端接收发送端发送的消息
- RabbitMQ(python实现)学习之三:Routing(接收端接收固定类型消息)
- Android端接入微信支付的详细流程
- 光纤端接的技巧
- struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式
- 基于mina服务器框架在android客户端接中文收不到消息以及发送不出中文的的问题
- 基于mina服务器框架在android客户端接中文收不到消息以及发送不出中文的的问题
- 基于mina服务器框架在android客户端接中文收不到消息以及发送不出中文的的问题
- struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式
- 高速PCB的终端端接
- mybatis拦截器的执行顺序
- Java中子类重写父类的思想本质
- 自己写的触壁反弹效果!!js
- Jquery 修改 动态生成的Html代码
- WebService到底是什么?
- RabbitMQ的Android端接收
- config库和operational库的区别
- Log4j配置spring+druid打印日志
- MYSQL 中实现split 功能
- IntelliJ IDEA 2016.2 注册码生成
- 系统闹钟 AlarmManager
- spring自带的定时任务功能,基于注解和xml配置
- 关于圆环进度条的问题
- spoj 220 PHRASES - Relevant Phrases of Annihilation(后缀数组)