实例介绍
【实例简介】
本实例采用SIPSorcery插件实现GB2818监控视频播放等功能,重点介绍SIP协议对报文的处理。
【实例截图】
【核心代码】
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Sinks.SystemConsole.Themes;
using SIPSorcery.SIP;
using SIPSorcery.SIP.App;
namespace SIPSorcery.SIPProxy
{
struct SIPAccountBinding
{
public SIPAccount SIPAccount;
public SIPURI RegisteredContact;
public SIPEndPoint RemoteEndPoint;
public SIPEndPoint LocalEndPoint;
public int Expiry;
public SIPAccountBinding(SIPAccount sipAccount, SIPURI contact, SIPEndPoint remote, SIPEndPoint local, int expiry)
{
SIPAccount = sipAccount;
RegisteredContact = contact;
RemoteEndPoint = remote;
LocalEndPoint = local;
Expiry = expiry;
}
}
class Program
{
private static int _listenPort = SIPConstants.DEFAULT_SIP_PORT; // The default UDP SIP port.
private static Microsoft.Extensions.Logging.ILogger logger = SIPSorcery.Sys.Log.Logger;
private static SIPTransport _sipTransport;
private static Dictionary<string, SIPAccountBinding> _sipRegistrations = new Dictionary<string, SIPAccountBinding>(); // [SIP Username, Binding], tracks SIP clients that have registered with the server.
static void Main()
{
try
{
Console.WriteLine("SIPSorcery SIP Proxy Demo");
AddConsoleLogger();
// Configure the SIP transport layer.
_sipTransport = new SIPTransport();
// Use default options to set up a SIP channel.
var sipChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.Any, _listenPort));
_sipTransport.AddSIPChannel(sipChannel);
var ipv6SipChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.IPv6Any, _listenPort));
_sipTransport.AddSIPChannel(ipv6SipChannel);
// Wire up the transport layer so SIP requests and responses have somewhere to go.
_sipTransport.SIPTransportRequestReceived = SIPTransportRequestReceived;
_sipTransport.SIPTransportResponseReceived = SIPTransportResponseReceived;
// If you want to see ALL the nitty gritty SIP traffic wire up the events below.
//_sipTransport.SIPBadRequestInTraceEvent = SIPBadRequestInTraceEvent;
//_sipTransport.SIPBadResponseInTraceEvent = SIPBadResponseInTraceEvent;
_sipTransport.SIPRequestInTraceEvent = SIPRequestInTraceEvent;
//_sipTransport.SIPRequestOutTraceEvent = SIPRequestOutTraceEvent;
//_sipTransport.SIPResponseInTraceEvent = SIPResponseInTraceEvent;
_sipTransport.SIPResponseOutTraceEvent = SIPResponseOutTraceEvent;
ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne();
}
catch (Exception excp)
{
Console.WriteLine("Exception Main. " excp);
}
}
/// <summary>
/// Handler for processing incoming SIP requests.
/// </summary>
/// <param name="localSIPEndPoint">The end point the request was received on.</param>
/// <param name="remoteEndPoint">The end point the request came from.</param>
/// <param name="sipRequest">The SIP request received.</param>
private static async Task SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
try
{
if (sipRequest.Method == SIPMethodsEnum.BYE)
{
throw new NotImplementedException();
}
else if (sipRequest.Method == SIPMethodsEnum.CANCEL)
{
throw new NotImplementedException();
}
else if (sipRequest.Method == SIPMethodsEnum.INVITE)
{
throw new NotImplementedException();
}
else if (sipRequest.Method == SIPMethodsEnum.OPTIONS)
{
SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
await _sipTransport.SendResponseAsync(optionsResponse);
}
else if (sipRequest.Method == SIPMethodsEnum.REGISTER)
{
SIPResponse tryingResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null);
await _sipTransport.SendResponseAsync(tryingResponse);
SIPResponseStatusCodesEnum registerResponse = SIPResponseStatusCodesEnum.Ok;
if (sipRequest.Header.Contact != null && sipRequest.Header.Contact.Count > 0)
{
int expiry = sipRequest.Header.Contact[0].Expires > 0 ? sipRequest.Header.Contact[0].Expires : sipRequest.Header.Expires;
var sipAccount = new SIPAccount(null, sipRequest.Header.From.FromURI.Host, sipRequest.Header.From.FromURI.User, null, null);
SIPAccountBinding binding = new SIPAccountBinding(sipAccount, sipRequest.Header.Contact[0].ContactURI, remoteEndPoint, localSIPEndPoint, expiry);
if (_sipRegistrations.ContainsKey(sipAccount.SIPUsername))
{
_sipRegistrations.Remove(sipAccount.SIPUsername);
}
_sipRegistrations.Add(sipAccount.SIPUsername, binding);
logger.LogDebug("Registered contact for " sipAccount.SIPUsername " as " binding.RegisteredContact.ToString() ".");
}
else
{
registerResponse = SIPResponseStatusCodesEnum.BadRequest;
}
SIPNonInviteTransaction registerTransaction = new SIPNonInviteTransaction(_sipTransport, sipRequest, null);
SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, registerResponse, null);
registerTransaction.SendResponse(okResponse);
}
else
{
logger.LogDebug("SIP " sipRequest.Method " request received but no processing has been set up for it, rejecting.");
}
}
catch (NotImplementedException)
{
logger.LogDebug(sipRequest.Method " request processing not implemented for " sipRequest.URI.ToParameterlessString() " from " remoteEndPoint ".");
SIPResponse notImplResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null);
await _sipTransport.SendResponseAsync(notImplResponse);
}
}
/// <summary>
/// Handler for processing incoming SIP responses.
/// </summary>
/// <param name="localSIPEndPoint">The end point the response was received on.</param>
/// <param name="remoteEndPoint">The end point the response came from.</param>
/// <param name="sipResponse">The SIP response received.</param>
private static Task SIPTransportResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse)
{
logger.LogDebug("Response received from " remoteEndPoint " method " sipResponse.Header.CSeqMethod " status " sipResponse.Status ".");
return Task.CompletedTask;
}
#region Non-functional trace/logging handlers. Main use is troubleshooting.
/// <summary>
/// Adds a console logger. Can be omitted if internal SIPSorcery debug and warning messages are not required.
/// </summary>
private static void AddConsoleLogger()
{
var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory();
var loggerConfig = new LoggerConfiguration()
.WriteTo.Console(theme: AnsiConsoleTheme.Code)
.Enrich.FromLogContext()
.MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug)
.WriteTo.Console()
.CreateLogger();
loggerFactory.AddSerilog(loggerConfig);
SIPSorcery.Sys.Log.LoggerFactory = loggerFactory;
}
private static void SIPRequestInTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
logger.LogDebug("REQUEST IN {0}->{1}: {2}", remoteEndPoint.ToString(), localSIPEndPoint.ToString(), sipRequest.StatusLine);
//logger.LogDebug(sipRequest.ToString());
}
private static void SIPRequestOutTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
logger.LogDebug("REQUEST OUT {0}->{1}: {2}", localSIPEndPoint.ToString(), remoteEndPoint.ToString(), sipRequest.StatusLine);
//logger.LogDebug(sipRequest.ToString());
}
private static void SIPResponseInTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse)
{
logger.LogDebug("RESPONSE IN {0}->{1}: {2}", remoteEndPoint.ToString(), localSIPEndPoint.ToString(), sipResponse.ShortDescription);
//logger.LogDebug(sipResponse.ToString());
}
private static void SIPResponseOutTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse)
{
logger.LogDebug("RESPONSE OUT {0}->{1}: {2}", localSIPEndPoint.ToString(), remoteEndPoint.ToString(), sipResponse.ShortDescription);
//logger.LogDebug(sipResponse.ToString());
}
private static void SIPBadRequestInTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, string message, SIPValidationFieldsEnum sipErrorField, string rawMessage)
{
logger.LogWarning("Bad SIPRequest. Field=" sipErrorField ", Message=" message ", Remote=" remoteEndPoint.ToString() ".");
}
private static void SIPBadResponseInTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, string message, SIPValidationFieldsEnum sipErrorField, string rawMessage)
{
logger.LogWarning("Bad SIPResponse. Field=" sipErrorField ", Message=" message ", Remote=" remoteEndPoint.ToString() ".");
}
#endregion
}
}
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)