我有一个服务器应用程序——在极少数发生意外错误的情况下——应该向 lync 用户(端点)发送即时消息。
根据我的阅读,我无法使用 Lync Client SDK,因为它依赖于应用程序服务器上正在运行的 Lync 客户端。然而这是不可能的。UCWA 似乎是一个公平的选择,但我真的不想开始编写自己的 Lync API,将所有 HttpClient 聊天隐藏在托管代码包装器中。
对于这个简单的用例,我最好的选择是什么?
我有一个服务器应用程序——在极少数发生意外错误的情况下——应该向 lync 用户(端点)发送即时消息。
根据我的阅读,我无法使用 Lync Client SDK,因为它依赖于应用程序服务器上正在运行的 Lync 客户端。然而这是不可能的。UCWA 似乎是一个公平的选择,但我真的不想开始编写自己的 Lync API,将所有 HttpClient 聊天隐藏在托管代码包装器中。
对于这个简单的用例,我最好的选择是什么?
我建议使用UCMA - 统一通信托管 API。如果它是您发送的一次性即时消息并且您不需要可扩展以处理许多同时对话等的应用程序,您可以使用 UserEndpoint,因为它比 ApplicationEndpoint 的工作和设置要少一些。
我在我的博客上有一个这样做的工作示例:http: //thoughtstuff.co.uk/2013/03/creating-ucma-applications-with-a-userapplication-instance-example-sending-ims/它也有有关您拥有的不同选项的更多信息。
但是,为了完整起见(并且因为 SO 会比我预期的博客长!)这里是代码:
using Microsoft.Rtc.Collaboration;
using System;
namespace SimpleUserUCMA
{
class Program
{
private const string sipaddress = "sip:from@domain.com";
private const string username = "USERNAME";
private const string password = "PASSWORD";
private const string domain = "DOMAIN";
private const string destinationSip = "sip:tom@domain.com";
private const string IMMessage = "Hello!";
static CollaborationPlatform _collabPlatform { get; set; }
static UserEndpoint _endpoint { get; set; }
static bool _OKToQuit = false;
static void Main(string[] args)
{
string userAgent = "ClientPlatformExample";
var platformSettings = new ClientPlatformSettings(userAgent, Microsoft.Rtc.Signaling.SipTransportType.Tls);
_collabPlatform = new CollaborationPlatform(platformSettings);
//Start up the platform, calling back asynchronously once it's done.
_collabPlatform.BeginStartup(EndCollabPlatformStartup, null);
//In this example, wait for everything to finish before exiting
while (!_OKToQuit)
{
System.Threading.Thread.Sleep(2000);
}
}
private static void EndCollabPlatformStartup(IAsyncResult ar)
{
_collabPlatform.EndStartup(ar);
//A collaboration plaform can have one or more Endpoints. An Endpoint is tied to a SIP Address.
UserEndpointSettings settings = new UserEndpointSettings(sipaddress);
settings.Credential = new System.Net.NetworkCredential(username, password, domain);
settings.AutomaticPresencePublicationEnabled = true;
_endpoint = new UserEndpoint(_collabPlatform, settings);
_endpoint.BeginEstablish(UserEndpointEstablishCompleted, null);
}
private static void UserEndpointEstablishCompleted(IAsyncResult ar)
{
_endpoint.EndEstablish(ar);
//Once the endpoint is in place, create a Conversation and an IM Call.
var Conversation = new Conversation(_endpoint);
var Call = new InstantMessagingCall(Conversation);
//When the call is established, Flow will be created. Flow is how you sent IMs around. Therefore, just before
//establishing, we attach an event handler to catch the flow being setup (it's state will change to Active)
Call.InstantMessagingFlowConfigurationRequested += Call_InstantMessagingFlowConfigurationRequested;
Call.BeginEstablish(destinationSip, new CallEstablishOptions(), EndBeginEstablish, Call);
}
private static void EndBeginEstablish(IAsyncResult ar)
{
Call call = (Call)ar.AsyncState;
call.EndEstablish(ar);
}
static void Call_InstantMessagingFlowConfigurationRequested(object sender, InstantMessagingFlowConfigurationRequestedEventArgs e)
{
//Once we're notified about this, we get a handle to the newly created Flow. Let's use this to register for state changes.
e.Flow.StateChanged += Flow_StateChanged;
}
static void Flow_StateChanged(object sender, MediaFlowStateChangedEventArgs e)
{
if (e.State == MediaFlowState.Active)
{
//The flow is now active! We can use it to send messages.
InstantMessagingFlow flow = (InstantMessagingFlow)sender;
flow.BeginSendInstantMessage(IMMessage, EndBeginSendInstanceMessage, flow);
}
}
private static void EndBeginSendInstanceMessage(IAsyncResult ar)
{
InstantMessagingFlow flow = (InstantMessagingFlow)ar.AsyncState;
flow.EndSendInstantMessage(ar);
//Having sent the message, terminate the conversation
flow.Call.Conversation.BeginTerminate(EndBeginTerminate, flow.Call.Conversation);
}
private static void EndBeginTerminate(IAsyncResult ar)
{
Conversation conversation = (Conversation)ar.AsyncState;
conversation.EndTerminate(ar);
_OKToQuit = true;
}
}
}