UCMA4初体验

小编 2026-06-09 阅读:1950 评论:0
进入新公司需要新技能。以前从来没用过C#,但是现在的项目是Lync API开发,只能抓紧...

进入新公司需要新技能。以前从来没用过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"/>

 注意不要删掉数字后缀。

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

 

 

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

上一篇:Golang new和 make的区别 下一篇:分块打表
热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表