2014-01-20 88 views
0

我正嘗試在C#SIP客戶端項目中使用來自codeplex的sip巫術來發送和接收請求並響應我的服務器。當我使用SIPUDPChannel.Send('remoteEP','msg')時,我可以看到SUBSCRIBE數據包被髮送到我的服務器,並且我的服務器以狀態響應迴應。使用SIP-Sorcery訂閱響應C#

但是,我如何使用SIP Sorcery API捕獲響應/請求事件?

+0

你能發表你的代碼片段嗎? – sipwiz

+0

我想出瞭如何接收回應。這是一個片段http://pastebin.com/pNqLYpc7 但是,我現在有另一個問題(ofcause)。當我在Transport_SIPTransportResponseReceived()中發送一個新的channel.Send()時,我可以看到它正在發送對話框,它不應該發送,因爲我還沒有被服務器認證。 任何方式,我可以做出一個新的請求與響應的WWW身份驗證,而不必在一個對話框內的請求? – grmihel

回答

1

回答第二個問題,你已經在第二個問題中發表了關於爲什麼第二個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); 
} 
+0

在創建到我的服務器的傳輸/信道連接時,是否有任何方法來應用用戶名和密碼? – grmihel

+0

謝謝。這使它爲我工作。 – grmihel

+0

前一個線程的短暫跟進。如果我想在收到來自服務器的NOTIFY消息後發送200 OK數據包,是否可以這樣做http://pastebin.com/QQz0gfvt? – grmihel