Azure Lei Zhang的博客

weibo: LeiZhang的微博/QQ: 185165016/QQ群:319036205/邮箱:leizhang1984@outlook.com/TeL:139-161-22926

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  390 随笔 :: 0 文章 :: 394 评论 :: 0 引用

  《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实战》——(美)白海石,机械工业出版社

 

posted on 2015-04-14 18:02 Lei Zhang的博客 阅读(...) 评论(...) 编辑 收藏