我正尝试在C#SIP客户端项目中使用来自codeplex的sip巫术来发送和接收请求并响应我的服务器。当我使用SIPUDPChannel.Send('remoteEP','msg')时,我可以看到SUBSCRIBE数据包被发送到我的服务器,并且我的服务器以状态响应回应。使用SIP-Sorcery订阅响应C#
但是,我如何使用SIP Sorcery API捕获响应/请求事件?
我正尝试在C#SIP客户端项目中使用来自codeplex的sip巫术来发送和接收请求并响应我的服务器。当我使用SIPUDPChannel.Send('remoteEP','msg')时,我可以看到SUBSCRIBE数据包被发送到我的服务器,并且我的服务器以状态响应回应。使用SIP-Sorcery订阅响应C#
但是,我如何使用SIP Sorcery API捕获响应/请求事件?
回答第二个问题,你已经在第二个问题中发表了关于为什么第二个SUBSCRIBE请求在对话框中(或更正确的事务中)的内容;不是。
但是,因为您正在重新使用您从第一个SUBSCRIBE请求的响应中获得的SIP标头,所以您最终将设置某些标头,使其看起来好像它是现有事务的一部分。
正确的做法是从您的原始SIP请求中重新使用标头,然后递增CSeq并重新生成CallID。下面的代码行(注意我没有编译它来检查语法错误)。
static SIPTransport Transport;
static SIPMessage msg;
static string inputMsg;
static SIPUDPChannel channel;
static SIPRequest subscribeRequest;
static void Main(string[] args)
{
InitializeSIP();
Console.Read();
}
static void InitializeSIP()
{
//ResolveIPEndPoint
SIPEndPoint sipep = new SIPEndPoint(new IPEndPoint(IPAddress.Parse("192.168.102.12"), 5060));
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.102.12"), 5060);
//Set Transport
Transport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine());
//IPEndPoint
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("192.168.100.10"), 8080);
//Create Channel object
channel = new SIPUDPChannel(localEndPoint);
Transport.AddSIPChannel(channel);
//Wire transport with incoming requests
Transport.SIPTransportRequestReceived += new SIPTransportRequestDelegate(Transport_SIPTransportRequestReceived);
//Wire transport with incoming responses
Transport.SIPTransportResponseReceived += new SIPTransportResponseDelegate(Transport_SIPTransportResponseReceived);
inputMsg = "SUBSCRIBE sip:[email protected] SIP/2.0" + SIPConstants.CRLF +
"Via: SIP/2.0/UDP 192.168.100.10:8080;rport;branch=z9hG4bKFBB7EAC06934405182D13950BD51F001" + SIPConstants.CRLF +
"From: <sip:[email protected]>;tag=196468136" + SIPConstants.CRLF +
"To: <sip:[email protected]>" + SIPConstants.CRLF +
"Contact: <sip:[email protected]>" + SIPConstants.CRLF +
"Call-ID: 1337505490-453410046-705466123" + SIPConstants.CRLF +
"CSeq: 1 SUBSCRIBE" + SIPConstants.CRLF +
"Max-Forwards: 70" + SIPConstants.CRLF +
"Event: Presence" + SIPConstants.CRLF +
"Content-Length: 0";
subscribeRequest = SIPRequest.ParseSIPRequest(inputMsg);
channel.Send(remoteEP, subscribeRequest.ToString());
}
static void Transport_SIPTransportResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse)
{
Console.WriteLine("Response method: " + sipResponse.Header.CSeqMethod);
if(sipResponse.StatusCode == 401 && sipResponse.Header.CSeqMethod == SIPMethodsEnum.SUBSCRIBE)
{
//Resubscribe with Digist
//SIP Header
SIPHeader header = subscribeRequest.Header;
header.CSeq++;
header.CallID = "some_new_callID";
header.AuthenticationHeader = sipResponse.Header.AuthenticationHeader;
header.Expires = 120;
//New Request
SIPRequest request = new SIPRequest(SIPMethodsEnum.SUBSCRIBE, new SIPURI(SIPSchemesEnum.sip, remoteEndPoint));
request.LocalSIPEndPoint = localSIPEndPoint;
request.RemoteSIPEndPoint = remoteEndPoint;
request.Header = header;
//Send request
channel.Send(remoteEndPoint.GetIPEndPoint(), request.ToString());
}
else
Console.WriteLine(string.Format("Error {0} {1}.", sipResponse.StatusCode, sipResponse.Status));
}
static void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
Console.WriteLine("Request body: " + sipRequest.Body);
}
更新:
您如下图所示的代码添加凭据SIP请求。请注意,验证标头是基于每个请求而不是每个传输或每个信道的基础。在sipsorcery代码中,SIPTransport可以具有多个SIPChannel,并且SIPChannel可以与多个SIP端点通信,因此在传输或通道上设置凭据没有任何意义。
SIPAuthorisationDigest authDigest = sipResponse.Header.AuthenticationHeader.SIPDigest;
authDigest.SetCredentials(username, password, uri, SIPMethodsEnum.INVITE.ToString());
authRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authDigest);
authRequest.Header.AuthenticationHeader.SIPDigest.Response = authDigest.Digest;
更新2:
要发送到SIP请求的响应简单最简单的方法如下所示。
static void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
SIPResponse response = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
_sipTransport.SendResponse(response);
}
你能发表你的代码片段吗? – sipwiz
我想出了如何接收回应。这是一个片段http://pastebin.com/pNqLYpc7 但是,我现在有另一个问题(ofcause)。当我在Transport_SIPTransportResponseReceived()中发送一个新的channel.Send()时,我可以看到它正在发送对话框,它不应该发送,因为我还没有被服务器认证。 任何方式,我可以做出一个新的请求与响应的WWW身份验证,而不必在一个对话框内的请求? – grmihel