`
somefuture
  • 浏览: 1078676 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

UCMA4初体验

阅读更多

进入新公司需要新技能。以前从来没用过C#,但是现在的项目是Lync API开发,只能抓紧从头开始了。

网络上关于UCMA4的文章并不多,微软的网站上可能有不少,还有一些视频,不过并不适合入门。有一个视频除外,我也是从这个视频开始学的:http://channel9.msdn.com/posts/UCMA-Hello-World-Send-an-Instant-Message (UCMA Hello World - Send an Instant Message)

虽然入门教程不多,但是概念讲解的还不少。比如这个:http://www.cnblogs.com/vipyoumay/archive/2012/01/12/2320801.html

http://msdn.microsoft.com/library/office/dn465943(office.15)

你可以选择先看看上面的东西,详细了解下,然后接着读这篇文章。

 

UCMA4和UCMA3有什么区别我不知,因为我每接触过后者,不过后者的用户群应该远大于前者。

UCMA4的连接搭建流程很清晰,直接看代码。下面的代码和视频里的基本一致:

    class Program
    {
        string conversationSubject = "let's go";
        string messageText = "it's a sunny day.";
        InstantMessagingCall imCall;
        InstantMessagingFlow imFlow;
        UserEndpoint userEndpoint;
        UCMASampleHelper helper;
        AutoResetEvent completeEvent = new AutoResetEvent(false);
     ...

 在使用之前先来几个变量。字符串的不说了,你看下哪里用到就知道干什么的了。

 

ucma中有两种“终端”:USERENDPONT和APPLICATIONENDPOINT。第二个功能更强大也更难用,目前也不需要。可以自己看一下:http://blog.thoughtstuff.co.uk/2014/01/ucma-endpoints-choosing-between-application-and-user-endpoints/

因为我们使用UCMA是希望和Lync客户端进行通信,所以需要一个发起通信的客户端(当然是用API模拟的)。这个对象对应的类就是UserEndpoint,所以我们建立一个他的对象userEndpoint。上面的两个对象,imCall是InstantMessagingCall的实例,用了建立连接的(是和另一个客户端的连接,不是和服务器的)。imFlow是InstantMessagingFlow的实例,用了处理业务的,比如这里要发送的消息。

为了简化,这里用到了UCMASampleHelper类。视频里很详细的说了怎么引入该类:

using Microsoft.Rtc.Collaboration.Sample.Common;
...
namespace Microsoft.Rtc.Collaboration.Sample.Common
{
    class UCMASampleHelper
    {

 你可以把using子句去掉,改成:

namespace xxx//xxx和Program类是一样的
{
    class UCMASampleHelper
    {

 completeEvent是多线程里的一个信号量。我刚刚接触C#,UCMA里用到不少异步、委托、多线程的技能,我不是很了解他们和java中的区别,所以不多说了。估计看这篇文章的都比我懂。

 

在主要的Run方法里,操作如下:

...
private void Run()
        {
            helper = new UCMASampleHelper();
            userEndpoint = helper.CreateEstablishedUserEndpoint("hello_world");
            Console.WriteLine("the endpoint is owned by " + userEndpoint.OwnerUri);

            ConversationSettings conversationSettings = new ConversationSettings();
            conversationSettings.Subject = conversationSubject;
            Conversation conversation = new Conversation(userEndpoint, conversationSettings);

            imCall = new InstantMessagingCall(conversation);
            imCall.InstantMessagingFlowConfigurationRequested += new EventHandler<InstantMessagingFlowConfigurationRequestedEventArgs>(imCall_InstantMessagingFlowConfigurationRequested);
            string targetUri = "sip:a.b.c@def.com";
            imCall.BeginEstablish(targetUri, null, CallEstablishCompleted, null);
            completeEvent.WaitOne();
        }
...

 工具类里的CreateEstablishedUserEndpoint方法用于和服务器进行连接。下面再说这里。

 

终端连接后,就把他传给一个会话Conversation。UCMA里的对象多数建立的时候需要配置信息,所以这个会话也要一个ConversationSettings的实例。会话conversation生成后用来生成imCall。imCall中包含了第一个客户端的信息,所以还需要对方。通过sip协议指定一个对象targetUri(估计需要是同域的,不然连lync都连不上吧),然后调用imCall的BeginEstablish方法进行请求,成功后就调用CallEstablishCompleted方法。imcall一建立就会调用InstantMessagingFlowConfigurationRequested,我们给他委托一个事件,定义在方法imCall_InstantMessagingFlowConfigurationRequested里:

void imCall_InstantMessagingFlowConfigurationRequested(Object sender,InstantMessagingFlowConfigurationRequestedEventArgs e)
{
    imFlow = e.Flow;
    imFlow.StateChanged += new EventHandler<MediaFlowStateChangedEventArgs>(imFlow_StateChanged);
    imFlow.MessageReceived += new EventHandler<InstantMessageReceivedEventArgs>(imFlow_MessageReceived);
}

 imFlow状态改变时也有一个事件,定义在imFlow_StateChanged里:

void imFlow_StateChanged(object sender, MediaFlowStateChangedEventArgs e)
{
    if (e.State == MediaFlowState.Active)
    {
        imFlow.BeginSendInstantMessage(messageText, SendMessageCompleted, imFlow);
    }
}

 MediaFlowState有三个枚举:Idle,Active,Terminated。当变成Active时就发消息it's a sunny day.

收到消息时的事件处理定义在imFlow_MessageReceived中:

void imFlow_MessageReceived(object sender, InstantMessageReceivedEventArgs e)
{
    if (e.TextBody.Equals("using lync", StringComparison.OrdinalIgnoreCase))
    {
        Console.WriteLine("success,,, hello.");
    }
    else if (e.TextBody.Equals("bye", StringComparison.OrdinalIgnoreCase))
    {
        imFlow.BeginSendInstantMessage("shutting down...", SendMessageCompleted, imFlow);
        helper.ShutdownPlatform();
    }
    else
    {
        imFlow.BeginSendInstantMessage("ECHO: " + e.TextBody, SendMessageCompleted, imFlow);
    }
}

 很简单,对方给你回复using lync时控制台打印success,,, hello.回复bye时你自动回复shutting down...然后关掉;回复其他内容,你都自动回复ECHO:加他的内容。

其他回调方法为空。

 

上面主要是这个视频的内容。但是有一部分很需要留意:终端登录时怎么设置参数?

既然你要模拟一个客户端,你就需要一个用户名和他的密码,还要提供你要登录哪个服务器,你是在哪个域。

视频里没有讲到这一块,他演示了怎么获得一个App.config。

一个短的App.config是这样的:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- Please provide parameters necessary for the sample to run without 
    prompting for input -->

    <!-- Provide the FQDN of the Microsoft Lync Server -->
    <!--<add key="ServerFQDN1" value="ServerFQDN"/>-->

    <!-- The user name of the user that the sample logs in as -->
    <!-- You may leave this value as blank to use credentials of the currently 
    logged on user -->
    <!--<add key="UserName1" value="user"/>-->

    <!-- The user domain of the user that the sample logs in as -->
    <!-- You may leave this value as blank to use credentials of the currently 
    logged on user -->
    <!--<add key="UserDomain1" value="domain"/>-->

    <!-- The user URI of the user that the sample logs in as, in the format 
    user@host -->
    <!--<add key="UserURI1" value="user@host"/>-->
  </appSettings>
  <runtime>
   ...
  </runtime>
</configuration>

 这些参数不配置的话可以在控制台里交互。如果提供的话去掉注释就好,当然自己要改参数值。比如:

    <add key="ServerFQDN1" value="lync.miclozoft.com"/>
    <add key="UserName1" value="c.b.a"/>
    <add key="UserDomain1" value="ads.adsk.com"/>
    <add key="UserURI1" value="b.c.a@adsk.com"/>

 注意不要删掉数字后缀。

如果你提供的参数都是正确的,那就可以通信和发消息了。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics