我正在使用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)
答案 0 :(得分:0)
你的问题是:
UserEndpointSettings settings = new UserEndpointSettings(sipaddress,"00.000.63.216",5061);
当您通过TLS连接时,servername不能是IP地址,它必须与从服务器返回的证书名称匹配。因此,您需要用户uri所在的FE池的服务器名称。
为什么不使用构造函数的非服务器版本?
UserEndpointSettings settings = new UserEndpointSettings(sipaddress);
让UCMA使用Skypes自动发现流程为您连接服务器?