《Windows Azure Platform 系列文章目录》
项目文件,请在这里下载
在笔者之前的文章中Windows Azure Service Bus (1) 基础
介绍了Service Bus支持主题(Topic)。如下图:
当2个客户端同时订阅了相同的主题(Topic)。当向这个Topic发送消息的时候,2个客户端会同时收到该消息。
笔者模拟一个在线聊天室的场景:
1.创建一个Windows Console命令行项目,编写相应的代码
2.运行项目,要求输入聊天室名称(即订阅了相同的主题Topic)
3.当2个客户端进入同一个聊天室的时候,彼此之间可以互相通信和收发消息
4.当第3个客户端进入另外一个客户端的时候,不可以收到之前2个客户端发来的消息
1.创建Windows Console项目,命名为ServiceBusScribe。图略。
2.增加新的类ChatRoom.cs,增加如下代码:
using Microsoft.ServiceBus; using Microsoft.ServiceBus.Messaging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ServiceBusScribe { class TextEventArgs :EventArgs { public ChatText ChatText{get; private set;} public TextEventArgs (ChatText chatText) { ChatText = chatText; } } class ChatRoom { public event EventHandler<TextEventArgs> TextReceived; public string Name { get; private set; } TopicClient mTopicClient; SubscriptionClient mSubscriptionClient; //your servicebus namespace here const string mConString = "Endpoint=sb://[YourServiceBusName].servicebus.chinacloudapi.cn/;SharedAccessKeyName=[YourServiceBusKey]"; public ChatRoom(string chatRoom, string userName) { Name = chatRoom; NamespaceManager nm = NamespaceManager.CreateFromConnectionString(mConString); TopicDescription desc = new TopicDescription(chatRoom); desc.AutoDeleteOnIdle = TimeSpan.FromMinutes(10); if (!nm.TopicExists(chatRoom)) //如果没有该Topic,则创建 nm.CreateTopic(chatRoom); if (!nm.SubscriptionExists(chatRoom, userName)) //如果有该Topic,则订阅 nm.CreateSubscription(chatRoom, userName); mTopicClient = TopicClient.CreateFromConnectionString(mConString, chatRoom); mSubscriptionClient = SubscriptionClient.CreateFromConnectionString(mConString, chatRoom, userName); mSubscriptionClient.OnMessage((m) => { var text = m.GetBody<ChatText>(); if (TextReceived != null) TextReceived(this, new TextEventArgs(text)); }); } public void Send(string user, int color, string text) { mTopicClient.Send(new BrokeredMessage(new ChatText(user, color, text))); } public void Close() { mSubscriptionClient.Close(); mTopicClient.Close(); } } }
注意:在上面的代码中,修改const string mConString参数,将连接字符串修改为我们自己的Service Bus连接字符串
核心代码为上面的构造函数Public ChatRoom中
3.增加新的类ChatText.cs,增加如下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization; namespace ServiceBusScribe { [DataContract] class ChatText { [DataMember] public string User { get; set; } [DataMember] public string Text { get; set; } [DataMember] public int Color { get; set; } public ChatText(string user, int color, string text) { User = user; Text = text; Color = color; } } }
4.修改Program.cs,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization; namespace ServiceBusScribe { class Program { static int linePos = 2; //当前显示行的位置 static int myColor = 1; //为用户随机指定的颜色 static Array mColors = Enum.GetValues(typeof(ConsoleColor)); static void Main(string[] args) { Random rand = new Random(); myColor = rand.Next(0, mColors.Length); //随机指定用户名颜色 Console.Clear(); Console.Write("请输入用户名:"); string userName = Console.ReadLine(); //输入新聊天室名,或者加入已有聊天室 Console.Write("请输入聊天室名:"); string chatRoom = Console.ReadLine(); //聊天室界面 Console.Clear(); Console.Write(userName); Console.SetCursorPosition(Console.WindowWidth - chatRoom.Length, 0); Console.Write(chatRoom); Console.Write(new String('*', Console.WindowWidth)); Console.SetCursorPosition(0, Console.WindowHeight - 4); Console.Write(new String('*', Console.WindowWidth)); ChatRoom room = new ChatRoom(chatRoom, userName); room.TextReceived += room_TextReceived; while (true) { setCursorAtBottom(); var input = Console.ReadLine(); if (string.IsNullOrEmpty(input)) break; room.Send(userName, myColor, input); } room.Close(); } static void setCursorAtBottom() { //这个方法把光标放在屏幕底部,供用户输入新信息 Console.SetCursorPosition(0, Console.WindowHeight - 3); Console.Write(new String(' ', Console.WindowWidth)); Console.SetCursorPosition(0, Console.WindowHeight - 3); Console.Write("] "); } static void room_TextReceived(object sender, TextEventArgs e) { if (linePos >= Console.WindowHeight - 4) { for (int i = 2; i < Console.WindowHeight - 4; i++) { Console.SetCursorPosition(0, i); Console.Write(new string(' ', Console.WindowWidth)); } linePos = 2; } //显示接受到的新消息 Console.SetCursorPosition(0, linePos); Console.ForegroundColor = (ConsoleColor)mColors.GetValue(e.ChatText.Color); Console.Write("[" + e.ChatText.User + "]:"); Console.ForegroundColor = ConsoleColor.White; Console.Write(e.ChatText.Text); linePos++; setCursorAtBottom(); } } }
5.项目创建完毕后,记得增加对Microsoft.ServiceBus命名空间的引用。
然后我们编译一下,并同时运行2个Windows Console实例。
首先输入不同的用户名。
然后再输入同样的聊天室名称,如下图的Game。
我们进入同一个聊天室,显示如下:
我们在左侧,以Jack身份输入Hello信息后。即可在两个聊天室窗口,同时看到聊天信息。如下图:
同样的道路,我们在右侧的聊天窗口中,以Tom身份输入信息,也可以在两个聊天室窗口,同时看到聊天信息。
6.最后,我们可以在Azure Management Portal,查看到我们创建的名为Game的Service Bus Topic,如下图:
上图中,Game是笔者创建的聊天室名称。
另外,我们在不关闭2个Windows Console窗口的情况下,可以看到Subscription Count为2。即2个客户端订阅了该Topic。
参考文档:
《Windows Azure实战》——(美)白海石,机械工业出版社