如何将UCMA 4.0 / 5.0客户端连接到LYNC服务器

时间:2017-11-10 13:39:44

标签: lync skype-for-business ucma

我正在使用UserEndpoint创建一个UCMA客户端应用程序。当连接到我们组织的内部域内的Lync服务器时,我的UCMA应用程序能够与服务器建立连接。

using System;
using System.Threading;
using Microsoft.Rtc.Collaboration;

namespace SimpleUserUCMA
{
    class Program
    {
        private const string sipaddress = "sip:example@domain.com";
        private const string username = "example@domain.com";
        private const string password = "password@1234";
        private const string domain = "domain.com";
        private const string destinationSip = "liveagent1@ngwplab.com";//serveraddress@domain.com
        private const string IMMessage = "Hello";


        static CollaborationPlatform _collabPlatform { get; set; }
        static UserEndpoint _endpoint { get; set; }
        static bool _OKToQuit = false;
        private static InstantMessagingCall call;
        private static InstantMessagingFlow flow;
        private static string incomingMessage;
        private static ManualResetEvent incomingMessageWaiter = new ManualResetEvent(false);
        private static ManualResetEvent flowWaiter = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            string userAgent = "Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36";

            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);

            // Wait for a message to arrive and the flow to be ready.
            incomingMessageWaiter.WaitOne();
            flowWaiter.WaitOne();

            // Process the incoming message. For this example just echo what was received.
            var reply = "You send me: " + incomingMessage;

            // And reply to the sender.
            SendReplyMessage(reply);
            //In this example, wait for everything to finish before exiting
            while (!_OKToQuit)
            {
                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,"00.000.63.216",5061);
            settings.Credential = new System.Net.NetworkCredential(username, password, domain);
            settings.AutomaticPresencePublicationEnabled = true;

            _endpoint = new UserEndpoint(_collabPlatform, settings);
            _endpoint.BeginEstablish(UserEndpointEstablishCompleted, _endpoint);

        }


        private static void UserEndpointEstablishCompleted(IAsyncResult ar)
        {

            try
            {
                var currentEndpoint = ar.AsyncState as LocalEndpoint;
                <strong>currentEndpoint.EndEstablish(ar);</strong>

                //Once the endpoint is in place, wait for a conversation to arrive.
                _endpoint.RegisterForIncomingCall<InstantMessagingCall>(HandleInstantMessagingCall);
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR : " + ex);
            }


        }

        private static void HandleInstantMessagingCall(object sender, CallReceivedEventArgs<InstantMessagingCall> e)
        {
            if (e.ToastMessage != null && e.ToastMessage.HasTextMessage)
            {
                // Store the incoming message text.
                incomingMessage = e.ToastMessage.Message;
                // Signal that we have a message.
                incomingMessageWaiter.Set();
            }

            call = e.Call;
            call.InstantMessagingFlowConfigurationRequested += HandleInstantMessagingFlowConfigurationRequested;
            call.BeginAccept(EndCallAccept, null);
        }

        private static void EndCallAccept(IAsyncResult ar)
        {
            call.EndAccept(ar);
        }

        private static void HandleInstantMessagingFlowConfigurationRequested(object sender, InstantMessagingFlowConfigurationRequestedEventArgs e)
        {
            flow = e.Flow;
            flow.MessageReceived += HandleFlowMessageReceived;
            flow.StateChanged += HandleFlowStateChanged;
        }

        private static void HandleFlowMessageReceived(object sender, InstantMessageReceivedEventArgs e)
        {
            if (e.HasTextBody)
            {
                // Store the incoming message text.
                incomingMessage = e.TextBody;
                // Signal that we have a message.
                incomingMessageWaiter.Set();
            }

        }


        static void HandleFlowStateChanged(object sender, MediaFlowStateChangedEventArgs e)
        {
            if (e.State == MediaFlowState.Active)
            {
                // Signal that the flow is ready.
                flowWaiter.Set();
            }
        }

        private static void SendReplyMessage(string reply)
        {
            // Send the message to the requestor.
            flow.BeginSendInstantMessage(reply, EndBeginSendInstanceMessage, null);
        }

        private static void EndBeginSendInstanceMessage(IAsyncResult ar)
        {
            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;
        }
    }
}

但是当我尝试使用UCMA 5.0建立最终用户连接时出现错误

当我调试它时会在这一行中断:

var currentEndpoint = ar.AsyncState as LocalEndpoint;
currentEndpoint.EndEstablish(ar);

错误:

ERROR : ErrorCode=-2146893022
FailureReason=IncorrectNameInRemoteCertificate
LocalEndpoint=100.77.120.70:53578
RemoteEndpoint=52.176.63.216:5061
RemoteCertificate=<null>
Microsoft.Rtc.Signaling.TlsFailureException:The target principal name is incorrect ---> Microsoft.Rtc.Internal.Sip.TLSException: outgoing TLS negotiation failed; Wrong target principal name configured. HRESULT=-2146893022
   at Microsoft.Rtc.Internal.Sip.TlsTransportHelper.HandleNegotiationFailure(Int32 status, Boolean incoming)
   at Microsoft.Rtc.Internal.Sip.TlsTransportHelper.OutgoingTlsNegotiation(TransportsDataBuffer receivedData, TransportsDataBuffer& pDataToSend)
   at Microsoft.Rtc.Internal.Sip.TlsTransportHelper.NegotiateConnection(TransportsDataBuffer receivedData, TransportsDataBuffer& pDataToSend)
   at Microsoft.Rtc.Internal.Sip.TlsTransport.DelegateNegotiation(TransportsDataBuffer receivedData)
   at Microsoft.Rtc.Internal.Sip.TlsTransport.OnReceived(Object data)

1 个答案:

答案 0 :(得分:0)

你的问题是:

UserEndpointSettings settings = new UserEndpointSettings(sipaddress,"00.000.63.216",5061);

当您通过TLS连接时,servername不能是IP地址,它必须与从服务器返回的证书名称匹配。因此,您需要用户uri所在的FE池的服务器名称。

为什么不使用构造函数的非服务器版本?

UserEndpointSettings settings = new UserEndpointSettings(sipaddress);

让UCMA使用Skypes自动发现流程为您连接服务器?