RabbitMQ-CookBook-第4章-混合使用不同技术

RabbitMQ-CookBook-第4章-混合使用不同技术
在本章中我们将覆盖:
  1. 使用.NET client
  2. 通过MQTT绑定iPhone应用与RabbitMQ
  3. 在Andriod上使用消息来更新Google Maps
  4. 通过Andriod后端来发布消息
  5. 使用Qpid来交换RabbitMQ消息
  6. 使用Mosquitto来交换RabbitMQ消息
  7. 使用.NET clients来绑定WCF程序
介绍
在前面的章节中,我们已经介绍了基本概念。现在,我们要使用这些概念来创建真实的应用程序。在这里我们不会讲解AMQP新的概念,但你会看到RabbitMQ的一些典型用法,我们会让RabbitMQ与其它技术进交互,以实现终端用户为桌面和移动平台上的应用程序。 事实上RabbitMQ / AMQP与一般的消息传递技术一样,其主要目的是分离分布式应用程序中的不同模块,这样使其很容易地混合多种技术,并可有广泛的选择。
使用.Net client
.NET是一个官方的RabbitMQ clients。在这个例子中,我们将使用它来创建一个订阅者 。我们会使用Microsoft Windows Presentation Foundation (WPF)来创建我们第一个桌面程序。 可通过 http://msdn.microsoft.com/en-us/library/ms754130.aspx来了解更多信息.
我们会将.NET client绑定到第1章使用AMQP中广播消息食谱中的Java dispatcher上。你可在Chapter04/Recipe01目录中找到例子的源码.
准备
你需要Visual Studio 2008或更新的版本, .NET framework 3.5 或 4以上版本,以及RabbitMQ .NET client包, RabbitMQ.Client.dll,这些你可在https://www.rabbitmq.com/dotnet.html下载.
如何做
为了实现使用RabbitMQ来消费消息的 .NET 程序,我们需要执行下面的步骤:
1. 创建一个WPF应用程序,然后添加RabbitMQ.Client.dll引用.
2. 连接broker:
connection_factory.Uri = "amqp://guest:guest@" +edRabbitmqHost.Text + ":5672/";
3. 在myLastnews.fanout_01/06 交换器上绑定一个临时队列:
String myqueue = channel.QueueDeclare().QueueName;
channel.QueueBind(myqueue,news_exchange, "");
4. 启动一个订阅者线程:
sub = new Subscription(channel, myqueue, true);
StartSubscriberThread(sub);
5. 接收消息:
foreach (BasicDeliverEventArgs e in sub) {
...
Encoding.UTF8.GetString(e.Body);
}

6. 将消息写入列表框:
Action<String> action = delegate(String value){lsnews.Items.Insert(0,value);};
Dispatcher.BeginInvoke(action,Encoding.UTF8.GetString(e.Body));

如何工作
client绑定到了myLastnews.fanout_01/06交换器上(已在第1章的使用AMQP的广播消息食谱中创建).一旦将队列与交换器进行了绑定(步骤3),我们将使用StartSubscriberThread(sub)来启动一个新的线程,且方法会会执行new Thread(() => InternalStartSubscriber(sub)) (步骤4). 收到的消息(步骤5)将会使用BeginInvoke()方法将其添加到列表框中.
为了试验这个例子,你们执行下面的操作:
  1. 从Chapter01/Recipe06/Java_6 中使用 java -cp ./ rabbitmq-client.jar rmqexample.Publish来运行publisher
  2. 运行 .NET client并连接broker ‰ 结果如下图所示:
更多
AMQP的其中一个目标是集成不同开发语言,我们应该已经学会了如何使用下面的语言来分发相同的消息:
  1. Java
  2. Python
  3. Ruby
  4. .NET
‰ 在后面的食谱中,我们将增加其它clients和技术.
也可参考
更全面的文档,请访问https://www.rabbitmq.com/dotnet.html.

通过MQTT来绑定iphone app与RabbitMQ
MQTT (Message Queue Telemetry Transport,消息队列遥测传输)是一种快速且轻量的开源协议. MQTT广泛用于物联网。更多信息,可查看http://mqtt.org/ 和http://en.wikipedia.org/wiki/Internet_of_Things.
在本例中,我们将通过使用Mosquitto(http://mosquitto.org/)包的MQTT创建一个app来绑定ios移动设备与RabbitMQ .
我们也将看到如何来接收由下面的程序发出的消息:
  1. 在第3章节管理RabbitMQ-通过浏览器来管理RabbitMQ食谱中提出的RabbitMQ web 管理应用程序来
  2. 在第1章节使用AMQP-使用topic交换器来处理消息食谱中介绍的publisher
你可在Chapter04/Recipe02目录中找到此例的源码.

TIP
通过MQTT,可以发送和接收消息,但它不是Apple Push 通知的替换物.

准备 
跟随本食谱,你需要:
  1. Apple Xcode IDE (https://developer.apple.com/xcode/)
  2. iOS开发包(https://developer.apple.com/library/ios/navigation/)
  3. Mosquitto C 包(https://bitbucket.org/oojah/mosquitto/src)
如何做
在本例中,我们需要启用MQTT插件以允许MQTT clients连接,然后按下面的步骤来创建一个iOS应用程序:
1. 使用 rabbitmq-plugins enable rabbitmq_mqtt 命令来在RabbitMQ上安装MQTT插件.
2. 重启RabbitMQ.
3. 创建一个无ARC (Automatic Reference Counting)的新Xcode project,如下所示:


4. 下载Mosquitto C 包(https://bitbucket.org/oojah/mosquitto/src) ,将从它的lib目录中拷贝 .h,.c 文件到示例树的libmosquitto空目录中.
5. 导入Moquitto C包,并将包添加到 project property Header search path.
6. 在你的MQTT接口文件中添加下面的include指令:
#include "mosquitto.h"
7. 要使用包来启动,你必须使用mosquitto_lib_init()来初始化;
8. 创建一个适用于所有操作的struct mosquitto *mosq;
9. 使用 mosq = mosquitto_new(NULL, true, self)来初始化struct;.
10. 使用下面的代码来罪魁祸首RabbitMQ broker:
mosquitto_username_pw_set(mosq, NULL, NULL);
mosquitto_connect(mosq, cip, 1883, 60);
11. 使用下面的代码来订阅队列:
mosquitto_subscribe(mosq, NULL, "tecnology.rabbitmq.ebook", 0);
12. 使用mosquitto_message_callback_set(mosq,on_message)来设置消息回调;

13. 使用mosquitto_loop(mosq,1, 1)来开启循环来接收服务端消息;
14. 你的app准备好后,你就可以发送消息了。首先,你可以使用web管理控制台:切换到amq.topic交换器,并使用路由键technology.rabbitmq.ebook来发布消息.
15. 如果你想使用第1章节使用AMQP-使用topic交换器来处理消息路由食谱中的Java publisher,你需要使用路由键technology.rabbitmq.ebook将myTopicExchangeRoutingKey_01/08交换器与amq.topic 交换器进行绑定,正如我们在第2章节中超载AMQP标准-理解交换器到交换器食谱中看到的一样(译者注:绑定除了可发生在队列与交换器外,也可以绑定交换器和交换器)。
16. 使用mosquitto_disconnect(mosq) 来断开client,随后mosquitto_destroy(mosq)将释放struct.
17. 最后,使用mosquitto_lib_cleanup()来释放包资源。

如何工作
从版本3.0开始, RabbitMQ支持MQTT协议. 你可以使用rabbitmq-plugins来启用. Mosquitto是最流行的MQTT实现。在这个例子中,我们使用了它的C client library.通过此插件,使得AMQP和MQTT之间可相互通信!
在初始化步骤后以及步骤9-12后,client就已经准备就绪了,这意味着iPhone已经创建了一个绑定到amq.topic 交换器上的队列,其路由键为
rabbitmq.ebook .现在你可以将队列视为一个普通的 AMQP队列.
现在打开web管理控制台(the Managing RabbitMQ from a browser recipe in Chapter 3Managing RabbitMQ),并使用绑定的路由键发送一个test message,如下所示:
你的iPhone现在已经收到了test message!
现在我们假设第1章节使用AMQP-使用topic交换器来处理消息路由食谱是一个庞大企业系统中的一部分,它是难于修改的。
你不能修改publisher和consumer的软件,但你需要将"book's" 信息重定向到iPhone.
非常简单!使用e-2-e扩展就可从管理控制台进行交换器绑定(参考第2章节超越AMQP标准-理解交换器到交换器食谱),在Add binding from this exchange panel中设置正确的路由键,如下所示:
交换器已经绑定了.现在我们可以执行第1章节使用AMQP-使用topic交换器来处理消息路由食谱中的操作,看看会发生什么?你会看到消息被正确地路由了!
所有通过路由键technology.rabbitmq.ebook来发送的消息都将被重定向到amq.topic exchange,然后再到你的iPhone app.
更多
在这个例子中,为了演示RabbitMQ能应用于多种应用上下文,我们混合使用了前面章节中学过的概念以及一些新的技术。
不修改现有软件,知道如何来添加或删除新模块,这非常重要.这很棒,不是吗?

TIP
如果Mosquitto server不在LAN内,在连接mosquitto_connect(mosq, cip, 1883, 60 /*keepalive*/ )配置正确的keep-alive参数是非常重要的。
也可参考
MQTT: http://mqtt.org/.
你需要阅读整个Mosquitto C client 文档:http://mosquitto.org/api/files/mosquitto-h.html.
TIP
You can run this example even on a MQTT server as test.mosquitto.org with the routing-key #.
Other interesting links are http://www.eclipse.org/paho/ and http://mqtt.org/2011/08/mqtt-used-by-facebook-messenger.

在Andriod上使用消息来更新Google Maps
RabbitMQ与Android使用起来是相当简单的; Dalvik虚拟机的字节码完全兼容桌面Java版本, 且RabbitMQ JAR文件包含的API文件也是一样的。
在本食谱中,
我们打算策划一个如何在移动应用程序中使用RabbitMQ的真实例子 ,特别是使用其它Andriod设备发送的AMQP消息来更新Google Maps上的位置。
但,本食谱中两食谱项目中的第一部分,因此,在这里我们主要关注于应用程序消息,在下一个食谱中,我们将展示如何在Andriod设备中使用消息逻辑 。
两个食谱也是互补的,在本食谱中,我们将在Anriod上展示RabbitMQ consumer,它将在地图上绘画出收到的位置.producer会在下个食谱中展示,它会通过RabbitMQ来发布位置. 你可以在Chapter04/Recip中找到本食谱中的源码。

准备
要使本食谱正常工作,你需要:
  1. Android SDK tools (http://developer.android.com/sdk/index.html)
  2. Andriod API至少为11的Android设备(Honeycomb 和 Android 3.0.x或更高), 并提供OpenGL ES 2.0支持
  3. 需要在Andriod设备上安装Google Play
如何做
1. 从Android SDK Manager中安装Google Play Services:
2. 从Eclipse中,创建一个新的Android application. 然后跟随向导,最小的SDK必须是API11. 创建一个空的Activity.
3. 仔细参照Google Play服务提供的说明:  http://developer.android.com/google/play-services/setup. html
以及如何使用Google Map Android API v2上的说明: https://developers.google.com/maps/documentation/android/start.
4. 将RabbitMQ library files (commons-cli-1.1.jarcommons-io-1.2.jar,and rabbitmq-client.jar)拷贝到project的libs目录.
5. 在由Eclipse向导创建的"Hello world!" TextView位置 ,插入一个片断—你可以编辑对应的XML布局文件activity_main.xml,并插入下面的内容:
<fragment
android:id="@+id/mapFragment"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
6. 创建一个包含经度位置和纬度位置简单的MapCmd类.
7. 创建单例枚举(enum)MapController,它实现了MapCmd类的线程安全FIFO队列.

8. 创建一个用于异步消费RabbitMQ消息的ActualConsumer类,正好我们在第1章,使用AMQP中看到的一样,并覆盖其handleDelivery方法:
public void handleDelivery(
String consumerTag,
Envelope envelope,
BasicProperties properties,
byte[] body) throws java.io.IOException {
String message = new String(body);
MapController.INSTANCE.AddCmdFromJson(message);
}
9. 创建RabbitmqHandler类,并暴露其Connect()和Disconnect()方法,在其内部,它将调用所有需要的RabbitMQ API,以使app异步消费消息。本类中自定义的连接参数将以常量的方式进行定义。
10. 创建UpdateMap类,其内部是Runnable 接口的MainActivity实例, 它会定期地执行绘画操作:
public class UpdateMap implements Runnable {
GoogleMapmMap;
publicUpdateMap(GoogleMapmMap_) {
mMap = mMap_;
}
@Override
public void run() {
MapController.INSTANCE.ExecuteCmds(mMap);
updateHandler.postDelayed(this, UPDATE_INTERVAL);
}
};
11. 在最初由Eclipse创建的MainActivity类中,填充OnCreate() 方法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMap = ((MapFragment)
getFragmentManager().findFragmentById(R.id.mapFragment)).getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
updateMap = new UpdateMap(mMap);
updateHandler = new Handler();
updateHandler.postDelayed(updateMap, UPDATE_INTERVAL);

rabbitmqHandler = new RabbitmqHandler();
AsyncTask<Void, Void, Void>aconnect = new
AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
rabbitmqHandler.Connect();
} catch (IOException e) {
// TODO handle this
}
return null;
}
};
aconnect.execute((Void)null);
}
12. 最后对称地实现OnDestroy()方法来清理连接和资源.

如何工作
为了要使用Google Maps, 则必须安装Google Play,以使其服务对于 Android SDK开发,调试,部署。另外,我们必须在Google API console
(https://code.google.com/apis/console)上注册过
Google Maps。
不要忘记在AndroidManifest.xml中插入你自己的key. 在我们的例子中,我们留了一个占位符:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="SET-YOUR-GOOGLE-ANDROID-MAPS-KEY-HERE"/>
在我们讲述了一个基础Google Maps 程序后(步骤 1-5),我们已经通过RabbitMQ中介,实现了从其它设备接收地球坐标的必要逻辑。
因为需要响应的安卓移动应用程序 ,必须 强制性从一个不同的线程上执行接收操作,而主线程则执行一些绘图和地图相关的操作。这就是我们要实现一个线程安全MapCmd类的 FIFO队列的原因,并使其对于  MapController 单例可用; MapCmd 对象是通过 RabbitMQ consumer线程,调用 MapController.INSTANCE.AddCmdFromJson()方法塞入队列的.

MapController FIFO 队列消费者是Android程序的主线程. 我们创建了一个Handler对象来从main线程中周期性地调用updateMap.run()方法,并从队列中消费MapCmd命令, 以及更新地图显示。
要完成这个应用程序,我们必须使用IP地址和RabbitMQ broker的凭证来定制RabbitmqHandler类,此类负责处理与RabbitMQ的连接以及消费者线程的创建。
在Andriod程序的的main activity 中,我们创建并初始化了RabbitmqHandler实例(步骤11), 但值得注意的是我们在AsyncTask匿名对象中已经调用了它的Connect()方法; 并且强制不在主线程(包含RabbitMQ连接的线程)中执行任何网络同步操作.
当我们在 Andriod设备上启动应用程序时,我们可以看到Google Maps会加载默认的世界地图,在我们发送消息前,什么都不会发生。要测试这个例子,需要在web浏览器中打开RabbitMQ管理控制台 (参考第3章节-管理RabbitmMQ中的从浏览器中管理RabbitMQ食谱); 我们应该能够看到一个从Andriod设备连接的临时队列.我们可以直接向这个队列发布消息,也可以将消息发布到amq.fanout交换器,并指定负载为JSON 格式,如下面的代码所示:
{"lat":44.4937,"lon":11.3430}
当我们提交消息后,应用程序会聚焦在这里. 通过发送多个这个点附近的坐标, 我们将绘制出下面的屏幕截图:

更多
在本食谱中,我们已经展示了如何在Andriod设备上开发基于消息通信的分布式应用程序.为了简单起见,我们省略了许多关于身份认证,负载均衡,安全的细节。
此外,这个例子只完成了项目的一半,在这里,我们只实现了消费者,以及从RabbitMQ控制台来发送JSON格式的消息。
项目的后半部分将在下个食谱中展示,在你跳到下个章节之前,你需要注意地理坐标的数据可以是任意的-例如,它也可以来自嵌入式GPS设备。

TIP
对于嵌入式设备的移动设备,出于性能优化,应该尽量使用MQTT,而不是使用native RabbitMQ AMQP协议,这一点,我们已经在通过MQTT来绑定iPhone app与RabbitMQ食谱中看到过了.

从Andriod后端发送消息
在本食谱中,我们将完成前面食谱中开始的项目。我们将实现一个Android app来发布当前设备的位置给RabbitMQ. 当然,这个例子相对于前一个例子来说,是比较简单的,因为我们不会在地图上绘制位置,但我们仍然会需要 Google Play 服务,因为我们需要使用它的位置服务。同时,对于设备上可用的位置传感器,它也提供了一个有用的抽象,以使应用程序能够兼容广泛的Andriod设备。

准备
要完成此食谱 ,我们需要:
  1. Android SDK 工具 (http://developer.android.com/sdk/index.html)
  2. 一台带Android API 11级以上(Honeycomb 和Android 3.0.x 或更高)的Andriod设备
  3. Andriod设备上安装有Google Play服务
如何做
1. 从Android SDK Manager中安装Google Play 服务,这已经在前面的食谱中看过了.
2. 创建 一个新的Android应用程序.跟随向导,需要的最小SDK必须是API11.创建一个空的Activity.
3. 仔细遵循Google的说明来设置Google Play服务(http://developer.android.com/google/play-services/setup.html).
4. 拷贝RabbitMQ library 文件(commons-cli-1.1.jarcommons-io-1.2.jar,and rabbitmq-client.jar)到项目的libs目录中.
5. 在由 Eclipse wizard创建Hello world! TextView的地方, 插入一个名为followmeSwitch的 switch widget.你可以编辑相应的XML layout文件activity_main.xml,并插入下面的代码:
<Switch
android:id="@+id/followmeSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="28dp"
android:text="@string/followme" />
6. 创建一个继承至IntentService的SenderService类.
7. 在MainActivity.java中设置开关动作:
final Switch fms =(Switch)findViewById(R.id.followmeSwitch);
fms.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButtonbuttonView,
booleanisChecked) {
if (isChecked) {
serviceIntent = new Intent(MainActivity.this,
SenderService.class);
startService(serviceIntent);
} else {
stopService(serviceIntent);
} }
});

如何工作
在本食谱中,我们接近了混合使用RabbitMQ和Android技术的另一种模式: 在后端来发布消息,即时是用户界面在Andriod设备上不可视。
首先,我们创建了一个带开关的标准Android应用程序:当打开时,我们可以向RabbitMQ broker来分发消息,当关闭时,我们可以停止消息的分发。
因此,我们将followmeSwitch操作绑定了SenderService中 (步骤7).记住这点是很重要的:当我们在Andriod服务中启动一个后台job时,后台事件依然是通过应用程序的主线程来执行的,并且我们也需要采用与设计Andriod GUIS时相同的响应方针.
但在我们的例子中,我们已经决定使用IntentService 帮助类来启动一个不间断运行的后端线程.在这个线程中,我们将连接broker,并且通过调用locationClient.getLastLocation()方法周期性地发送设备当前位置给RabbitMQ(参考步骤6中提到的源文件代码).

TIP
在这个例子中,我们使用了Andriod标准的序列化类android.util.JsonWriter来代替前面我们看到的RabbitMQ JSONWriter. 事实上,后者不能在Andriod设备上工作,因为Dalvik只包含了Java beans的子集,缺少了相关的反射.
只要用户关闭了开关,我们就会立即退出线程.通过在一台设备上运行此程序,并在另一台设备上运行前面食谱中的程序,我们可以通过RabbitMQ消息来交流我们的地理位置。
更多 
Google localization client library允许位置变化时触发事件,因此这应该是发送地理位置坐标的最佳方法。这种方案可以优化电池的使用,但为了简单起见,我们没有这样做。但就此应用程序来说,功能是完整的。你可以运行多个不同的设备来允当消费者-当我们将消息发送到fanout时,它们会同步的更新位置。你甚至可以并发地运行多个生产者,但当前实现只是将它们的数据混合在一起,如果要从多个不同设备来绘制多个不同轨迹,你需要替换fanout交换器,每个生产者需要使用topic交换器且带不同的路由键来发送消息。
使用 Qpid来交换RabbitMQ消息
在本食谱中,我们将看到如何使用RabbitMQ client来与Apache Qpid交互.
准备
你需要从http://qpid.apache.org/download.html下载 Qpid;我们使用的是Java版本.
如何做
1. 从前面的章节中来获取Java示例,如:第1章使用AMQP中的广播消息或使用topic交换器来处理消息路由食谱中的例子
2. 运行Qpid server.
3. 运行clients.

如何工作
当你从第1章使用AMQP中的广播消息中的例子来执行client的时候,Qpid server与的RabbitMQ的行为一样,如下所示:
TIP
QPid 使用相同的RabbitMQ端口,因此如果要在同一台机上运行这两者,你可以修改端口或者关闭RabbitMQ(端口冲突).
使用 Mosquitto来交换RabbitMQ消息
在这个例子中,我们会创建一个java proxy,此代理会获取来自Andriod后台来发布消息食谱例子中发布的消息,并将它们转发到任何一个移动OS,正如我们在通过MQTT来绑定iPhone应用程序到RabbitMQ食谱中看到的一样,可按下面的截图来使用MQTT服务器 :
准备
你需要Paho Java library client, 你可在http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/中找到.

如何做
1. 你需要创建一个amq.fanout交换器的消费者:
String myQueue = channel.queueDeclare().getQueue();
String myExchange = "amq.fanout";
channel.queueBind(myQueue,myExchange,"");
2. 使用Paho Java client来创建一个MQTT连接:
mqttClient = new MqttClient(MQTTip,
MqttClient.generateClientId());
mqttClient.connect();
3. 将获取到的GPS消息发送给MQTT服务器:
mqttClient.publish("follow.me", message, 0, false);
4. 当通过MQTT绑定iPhone app与RabbitMQ时,修改路由的topic:
mosquitto_subscribe(mosq, NULL, "follow.me", 0);
5. 当通过MQTT绑定iPhone app与RabbitMQ时,使用MQTT服务器IP的地址修改服务器的IP

如何工作
按照步骤1-3,我们已经创建了两个连接,一个是RabbitMQ,一个是MQTT服务器。
当Android app发送了一些消息时,消息者接收到消息后会使用mqttClient.publish("follow.me", message,0,false)将其发布Mosquitto server;.
在iPhone程序上,你需要使用follow.me来修改topic,你也需要修改服务器IP地址,结果如下面的屏幕截图所示:

因此,如果Android app启用了后,你可以在你的iPhone app中看经度和纬度.

TIP
我们使用了公共服务器test.mosquitto.org,在使用前,请先网站的免责声明.

更多
We have divided the broker's responsibility, one for the AMQP protocol and one for the MQTT protocol.
也可参考
你可在http://www.eclipse.org/paho/找到更多关于Paho的更多信息. 当你创建Paho Java client 源码时,构建器会在你的文件系统:
yourbasedir/org.eclipse.paho.mqtt.java/org.eclipse.paho.client.mqttv3/build/dist/javadoc中创建javadoc.

使用.Net来绑定WFC应用程序
在这个例子中,我们将展示如何使用不同的技术来构建一个分布式应用程序. 其目标是创建一个健康程序来收集本地网络应用程序的状态信息。如果出现问题的话,应用程序会触发警报并将其发送给移动设备,在这里,我们使用Amazon EC2云来提供高可用性。但,EC2不是强制性的.
我们将使用Windows Communication Foundation (WCF) 和 RabbitMQ WCF 服务模块来创建这个例子. WCF service 将扮演主机健康收集器,并且会有多个客户端会向WCF服务发送消息。
RabbitMQ service 模块允许在AMQP之上使用SOAP协议. 我们也会将消息重定向到 also redirect the messages to a mobile iOS application via MQTT using the proxy already seen in the recipe
Exchanging RabbitMQ messages with Mosquitto.
In this recipe, we are going to use AMQP, SOAP, and MQTT as protocols, RabbitMQ, WCF,and iOS as technologies, and finally, an AWS EC2 instance as the server. The architecture is
summarized in the following figure:

准备
你需要Visual Studio 2005或2008, .NET framework 3.5,以及RabbitMQ WCF 服务模块, 这些你可以在http://www.rabbitmq.com/dotnet.html中找到.
下载WCF library的zip包.

如何做
1. 创建一个WCF应用程序,然后通过拷贝project中libs目录下的RabbitMQ.ServiceModel.dll来配置RabbitMQ service模块. 接着通过右部按扭来打开App.config文件,并导航至Edit WCF configuration Advanced binding extension new 并选择刚刚拷贝的文件。
2. 通过导航至WCF configuration bindings new bind configuration来创建一个绑定, 并按下面的截图为配置RabbitMQ实例:
3. 通过导航至Edit configuration Endpoints New Service End point来配置WCF end point, 然后设置Contract为WcfLib.IService1rabbitmqExtension的Binding属性 (在步骤1中已配置), 以及rabbitmqBinding的BindingConfiguration属性(步骤2已配置). 其结果如下所示:
4. 导航至Edit configuration services endpoint new and insert soap.amqp:///来配置host.
5. 创建Service1接口方法SendMachineInfo(MachineInfomachine Info),并在Service1 类中实现.
6. 创建一个新的C# project,为了使用接口方法,还需要添加服务端依赖.
7. 配置client App.conf ,并为RabbitMQ service 模块添加配置 (步骤 1和2 ), 然后导航至Edit configuration Client endpoints and adding soap.amqp:///Service1来配置client service; 绑定截图如下
8. 使用ClientService :ClientBase<IService1>, IService1来启动client .
9. 使用base.Channel.SendMachineInfo(machineInfo)来调用接口;
10. 如果你喜欢,你可以修改Exchanging RabbitMQ messages with Mosquitto 食谱来向iphone发送警报.你只需要修改下面的行:
String myExchange = "amq.direct";
channel.queueBind(myQueue,myExchange,"/Service1");

如何工作
根据步骤1-4, 我们使用RabbitMQ继承了WCF 标准绑定, 并且我们创建了一个单向通信,它是一种发后即忘模式,且服务端只创建了一个绑定至 amq.direct 交换器的队列,其路由键为/Service1.
MachineInfo类是按照SOAP来编码的 (步骤9); 服务器随后会执行函数SendMachineInfo(MachineInfomachineInfo). SOAP消息作为AMQP消息的内嵌负载。在这个例子中,服务端将警告消息存储在C:\warningstatus.store文件中,clients每秒都会检查CPU和内存的使用情况,并在出现警告时执行远程调用。如果你执行步骤10,你就会在app中收到消息,就像下面展示的一样:
Mosqui
更多
在这个例子中,我们已经尝试使用了RabbitMQ Amazon Elastic Compute Cloud(EC2),以及不同网络中的WCF WCF客户机和服务器。理解RPC调用是由broker来保证,且与标准RPC调用(模块之间直接通信)有所区别,这是很重要的。在这种方式中,架构是松耦合的,RabbitMQ是当作bus来使用的,因此它可以附着不同的 clients.WCF 绑定是一种Microsoft架构与其它系统集成时的强有力工具。
你可以使用web管理控制台或命令行来监控队列。
通信也可以是双向的,使用两个队列:一个用于请求,另一个用于异步响应

也可参考
查看https://www.rabbitmq.com/dotnet.html 并找到 section A description of the WCF binding and Service Model.
查看http://aws.amazon.com/ec2/ 来了解更多关于Amazon EC2的信息;总之,我们也会在接下来的Amazon cloud章节中介绍.

你可能感兴趣的:(RabbitMQ-CookBook-第4章-混合使用不同技术)