公告:本博客为微软云计算中文博客的镜像博客。部分文章因为博客兼容性问题,会影响阅读体验。如遇此情况,请访问原博客。
本文是Windows Azure AppFabric入门教学的第七篇文章。我们知道,AppFabirc由Service Bus 和 Access Control Service组成,为了提高大家学习的热情,我们以一款使用了Service Bus的命令行多人聊天示例程序为案例来进行讲解。
最终效果如下:
前置条件
为了使后续的教程能够顺利进行,请确保如下软件或组件已被安装:
- Microsoft .NET Framework 3.5 SP1
- Microsoft Visual Studio 2008 SP1 (or above)
- AppFabric SDK
- Windows Azure Platform Training Kit - June Update(示例代码)
请确保您以拥有一定的WCF编程经验,若没有,请浏览这里以快速的初步了解WCF。
最后请确保已创建了一个AppFabric项目和一个服务命名空间。请参考这里。
原理:
我们首先了解一下该多人聊天程序的运作原理。
为了实现多播通信模式,Service Bus提供了名为netEventRelayBinding的绑定(binding)方法。该绑定在WCF上实现了一个发布/订阅(publish/subscribe)通信模式,其允许多个应用程序来订阅发送至某端点的信息。发送给该端点的任何信息都会被所有应用程序接受到。
netEventRelayBinding允许多个监听者(listener)将自己注册到由第一个发送者(sender)指定的URI上,对于每一个服务宿主(service host),如果其拥有一个监听着相同URI的端点,其便会隐式的成为一个订阅者(subscriber)。如果某客户端向URI发送消息,该消息便会被当前所有订阅的端点接收到。
代码:
在了解了通信原理之后,我们来看看具体代码是如何编写的。
在Windows Azure Platform Training Kit - June Update 安装目录下,Labs/IntroServiceBus/Source/Ex03-MulticastSample/begin/CS目录下,打开MulticastSample.sln工程。
1.1打开App.config,将下图2处红框内语句删除。(注意,此举只为简化示例工程,我们会在后续的教程中讲解App.config配置文件的细节。)
1.2将下图2处红框内改为binding="netEventRelayBinding"。这是为了利用netEventRelayBinding的多播功能。
1.3将下图三处红框内文字替换为您在Windows Azure platform AppFabric portal处所注册得到的信息。
Service Namespace Domain,Issuer Name 和Issuer Key的具体位置请参照下图。
2.打开IMulticastContract.cs, 添加如下蓝框内代码。
public interface IMulticastContract
{
[OperationContract(IsOneWay = true)]
void Hello(string nickname);
[OperationContract(IsOneWay = true)]
void Chat(string nickname, string text);
[OperationContract(IsOneWay = true)]
void Bye(string nickname);
}
熟悉WCF编程的朋友们一定对此非常熟悉,如果无WCF编程经验,请花数分钟时间转至这里 迅速的了解一下WCF。值得注意的是,netEventRelayBinding要求WCF的接口协定只能暴露单向(one way)的操作,所以所有的操作需要被标记为 "IsOneWay=true",来表明该操作只有单一的输入信息,没有对应的输出信息。我们经常会碰到此类场景:某个操作,没有任何返回值,并且客户端并不关心调用成功与否,此时我们便可以将接口协定标记为one-way。当然,此类接口协定不能返回任何参数(返回值需声明为void),任何在服务端抛出的异常也不会返回至客户端。具体请参考这里。
3打开MulticastService.cs,添加如下蓝框内代码。
public class MulticastService : IMulticastContract
{
void IMulticastContract.Hello(string nickname)
{
Console.WriteLine("[" + nickname + "] joins");
}
void IMulticastContract.Chat(string nickname, string text)
{
Console.WriteLine("[" + nickname + "] says: " + text);
}
void IMulticastContract.Bye(string nickname)
{
Console.WriteLine("[" + nickname + "] leaves");
}
}
这些都是常规的WCF程序编写的固定套路。
4.打开Program.cs,添加如下蓝框内代码
public static void Main()
{
...
Console.WriteLine("Press [Enter] to exit");
Console.WriteLine();
channel.Hello(nickname);
string input = Console.ReadLine();
while (!string.IsNullOrEmpty(input))
{
channel.Chat(nickname, input);
input = Console.ReadLine();
}
channel.Bye(nickname);
channel.Close();
channelFactory.Close();
host.Close();
}
验证:
至此,代码已经创建完毕,我们已经可以进行调试了。
右击项目,Debug->Start new Instance
输入会话名,例如:team1,之后输入用户名,例如:nicolas。
再次以Start new Instance 启动另一调试实例,同样输入与之前相同的会话名,例如:team1,输入与之前不同的用户名,例如leola。
最终效果如图:
探析:
大家是否为此感到兴奋呢?究竟其内部原理如何呢?接下来我会为大家一探究竟!
打开Program.cs文件,如下图。
程序分为2部分,44行之前,程序以Server的角色运行,之后便成为Client角色。
我们会看到在server部分,代码会将Multicast服务托管至URI "sb://[yourServiceNamespace].servicebus.windows.net/[chatSessionName]/MulticastService/" 上。
此时,如果有另一个程序实例,运行,以同样的服务命名空间(ServiceNamespace)和会话名(SessionName),并试图监听同一个URI时会如何呢?
我们在之前提到过,在netEventRelayBinding 的binding模式下,如果端点监听的URI相同的话,其便会隐式的成为该URI的一个订阅者(subscriber)。
而在client部分,相信熟悉WCF的朋友都了然于胸了。当调用channel.Chat(nickname, input)时,由于netEventRelayBinding 特殊的通信模式,会将信息在订阅者之间进行组播。(注意,发送者也会被接收到信息)
不知道大家是否注意到,托管于Service Bus上的解决方案都只需通过URI便能向其发送或监听信息,这便会带来安全问题,我们可以通过ACS的帮助来确保其安全性,如果需要了解更多ACS方面的内容,敬请关注本博客。
好了,大家赶快动手试一下,进入奇妙的AppFabric世界吧!