首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Sorcery C#订阅响应

使用Sorcery C#订阅响应
EN

Stack Overflow用户
提问于 2014-01-20 12:43:23
回答 1查看 1.8K关注 0票数 1

我试图在一个C# sip客户端项目中使用codeplex的SIP巫术向我的服务器发送和接收请求和响应。当我使用SIPUDPChannel.Send('remoteEP','msg')时,我可以看到一个订阅包被发送到我的服务器,并且我的服务器用状态响应进行应答。

但是如何使用Sorcery捕获响应/请求事件?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-21 22:38:04

在回答第二个问题时,您在评论中提到了为什么第二个订阅请求是在对话框中(或者更正确地说,是在事务中);它不是。

但是,由于您正在重新使用从响应到第一个订阅请求的SIP报头,您将以一种使其看起来像是现有事务的一部分的方式设置一些报头。

正确的方法是重复使用原始SIP中的报头,并增加CSeq并重新生成CallID。下面代码的代码(注意,我没有编译它以检查语法错误)。

代码语言:javascript
复制
    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:myUSer@192.168.102.12 SIP/2.0" + SIPConstants.CRLF +
        "Via: SIP/2.0/UDP 192.168.100.10:8080;rport;branch=z9hG4bKFBB7EAC06934405182D13950BD51F001" + SIPConstants.CRLF +
        "From: <sip:subscribeUser@192.168.102.12>;tag=196468136" + SIPConstants.CRLF +
        "To: <sip:myUser@192.168.102.12>" + SIPConstants.CRLF +
        "Contact: <sip:subscribeUser@>" + 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请求添加凭据,如下面的代码所示。请注意,身份验证标头是基于每个请求,而不是基于每个传输或每个信道。在耗散代码中,SIPTransport可以具有多个SIPChannel,而SIPChannel可以与多个SIP端点通信,因此在传输或信道上设置凭据是没有意义的。

代码语言:javascript
复制
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请求发送简单响应的最简单方法如下所示。

代码语言:javascript
复制
static void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
    SIPResponse response = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
    _sipTransport.SendResponse(response);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21234488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档