📄 sipconnectionbase.cs
字号:
namespace Imps.Client.CommLayer.Common
{
using Imps.Base.Sipc;
using Imps.Client.Base;
using Imps.Client.Base.Comm;
using Imps.Client.CommLayer;
using Imps.Client.Resource;
using Imps.Client.Utils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;
internal abstract class SipConnectionBase : ISipConnection, IDisposable
{
private object _context;
private long _NextCallId;
private SipConnectionOption _option;
private volatile ConnectionState _state;
private object _syncObjSendReceive = new object();
private Timer CheckMessageTimeOutTimer;
private Hashtable PairUpMessageList = new Hashtable();
private SipcParser Parser = new SipcParser();
protected const int SendCtrlMaxMessage = 100;
protected const int SendCtrlPeriod = 0xea60;
private readonly object stateSyncRoot = new object();
public event EventHandler<FailedEventArgs> ConnectFailed;
public event EventHandler<SipRequestReceivedEventArgs> RequestReceived;
public event EventHandler<SendFailedEventArgs> SendFailed;
public event EventHandler<StateChangedEventArgs> StateChanged;
public SipConnectionBase(object context)
{
this.Context = context;
this.Parser.MessageParsingFailed += new EventHandler(this.Parser_MessageParsingFailed);
this.Parser.RequestReceived += new SipcRequestReceivedEventHandler(this.Parser_RequestReceived);
this.Parser.ResponseReceived += new SipcResponseReceivedEventHandler(this.Parser_ResponseReceived);
}
private int _SendMessage(SipMessageBase msg)
{
int maxRetryTimes = this.GetMaxRetryTimes(msg);
byte[] buffer = msg.Message.ToBinary();
int num = 0;
while (true)
{
try
{
this.SendMessage(buffer);
MessageValue value2 = this.FindPairUpMessageValue(msg);
if (value2 != null)
{
value2.ResetTimerCounter();
}
this.OnSendSuccessed(msg);
break;
}
catch (Exception)
{
if (num >= maxRetryTimes)
{
throw;
}
Thread.Sleep((int) (this.Option.SendFaildDelay * 0x3e8));
}
num++;
}
ClientLogger.WriteSipc("Send", msg.Message);
return (num + 1);
}
protected virtual void AfterStateFieldUpdated(ConnectionState oldState, ConnectionState newState)
{
}
private void AppendPairUpMessage(SipMessageBase msg)
{
if (this.IsPairUpMessage(msg))
{
try
{
lock (this.PairUpMessageList)
{
if (this.FindPairUpMessage(msg.Message) == null)
{
MessageValue value2 = new MessageValue(msg);
this.PairUpMessageList.Add(new MessageKey(msg), value2);
}
}
}
catch (Exception exception)
{
ClientLogger.WriteConnection("PairUp Exception", 20, msg.ToString() + "\r\n\r\n" + exception.ToString(), 1);
}
}
}
private bool CheckMessage(SipMessageBase msg)
{
if (msg.Message.CallId == null)
{
ClientLogger.WriteGeneral("消息符合规范,缺少CallId消息头", msg.Message.ToString(), 20);
return false;
}
if (msg.Message.CSeq == null)
{
ClientLogger.WriteGeneral("消息不符合规范,缺少CSeq消息头", msg.Message.ToString(), 20);
return false;
}
if (msg.Message is SipcRequest)
{
SipcRequest request = msg.Message as SipcRequest;
if (request.Method != request.CSeq.Method)
{
ClientLogger.WriteGeneral("消息不符合规范,请求消息的Method与CSeq的Method不一致", msg.Message.ToString(), 20);
return false;
}
}
return true;
}
private void CheckMessageTimeOut(object state)
{
lock (this.PairUpMessageList)
{
if (this.PairUpMessageList.Count != 0)
{
List<MessageValue> list = null;
foreach (MessageValue value2 in this.PairUpMessageList.Values)
{
if (value2.GrowTimerCounter() < this.Option.Timeout)
{
continue;
}
if (list == null)
{
list = new List<MessageValue>(3);
}
list.Add(value2);
}
if (list != null)
{
List<MessageValue>.Enumerator enumerator = list.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
MessageValue mv = enumerator.get_Current();
if (mv.RetryTimes > 0)
{
this.RetrySendMessage(mv);
}
else
{
this.RemovePairUpMessage((SipMessageBase) mv);
this.RaiseWaitTimeoutEvent((SipMessageBase) mv);
}
}
}
finally
{
enumerator.Dispose();
}
}
}
}
}
private void ClearPairUpMessage()
{
lock (this.PairUpMessageList)
{
this.PairUpMessageList.Clear();
}
}
public virtual void Close()
{
if (this.CheckMessageTimeOutTimer != null)
{
this.CheckMessageTimeOutTimer.Dispose();
}
this.RaiseAllPairUpMessageSendFailed();
this.ClearPairUpMessage();
this.RequestReceived = null;
this.SendFailed = null;
this.ConnectFailed = null;
}
public abstract void Connect(string host, int port);
public virtual void Dispose()
{
if (this.State == ConnectionState.Connected)
{
this.Close();
}
GC.SuppressFinalize(this);
}
~SipConnectionBase()
{
if (this.State == ConnectionState.Connected)
{
this.Close();
}
}
private MessageValue FindPairUpMessage(SipcMessage msg)
{
return this.FindPairUpMessageValue(msg);
}
private MessageValue FindPairUpMessageValue(SipcMessage msg)
{
if (msg == null)
{
return null;
}
lock (this.PairUpMessageList)
{
MessageKey key = new MessageKey(msg);
if (this.PairUpMessageList.ContainsKey(key))
{
return (MessageValue) this.PairUpMessageList[key];
}
return null;
}
}
private MessageValue FindPairUpMessageValue(SipMessageBase msg)
{
return this.FindPairUpMessageValue(msg.Message);
}
private int GetMaxRetryTimes(SipMessageBase msg)
{
MessageValue value2 = this.FindPairUpMessageValue(msg);
if (value2 != null)
{
return value2.RetryTimes;
}
return msg.RetryTimes;
}
private bool IsPairUpMessage(SipcMessage msg)
{
if (msg != null)
{
if (msg is SipcResponse)
{
return true;
}
if (msg is SipcRequest)
{
return ((msg as SipcRequest).Method == "A");
}
}
return false;
}
private bool IsPairUpMessage(SipMessageBase msg)
{
if (msg == null)
{
return false;
}
return ((msg is SipRequest) || (msg is SipInviteResponse));
}
private bool IsTempResponse(SipcMessage msg)
{
if ((msg != null) && (msg is SipcResponse))
{
return ((msg as SipcResponse).StatusCode < 200);
}
return false;
}
protected void LogError(Exception ex)
{
ClientLogger.WriteConnectionFailed("通信层异常", ex.ToString());
}
public long NextCallId()
{
return Interlocked.Add(ref this._NextCallId, (long) 1);
}
protected virtual void OnMessageParsingFailed()
{
}
protected virtual void OnSendSuccessed(SipMessageBase message)
{
}
protected void ParseMessage(byte[] buffer)
{
this.Parser.Parse(buffer, 0, buffer.Length);
}
protected void ParseMessage(byte[] buffer, int begin, int count)
{
this.Parser.Parse(buffer, begin, count);
}
private void Parser_MessageParsingFailed(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate {
ClientLogger.WriteGeneral("解析接收数据时发生错误", this.Parser.GetUnderlyContent(), 30);
this.OnMessageParsingFailed();
this.Close();
});
}
private void Parser_RequestReceived(object sender, SipcRequestReceivedEventArgs e)
{
this.ReceiveMessage(e.Request);
}
private void Parser_ResponseReceived(object sender, SipcResponseReceivedEventArgs e)
{
this.ReceiveMessage(e.Response);
}
private void RaiseAllPairUpMessageSendFailed()
{
lock (this.PairUpMessageList)
{
foreach (MessageValue value2 in this.PairUpMessageList.Values)
{
SipMessageHelper.RaiseSendMessageFailed(value2.Message, null, StringTable.ClientCommLayerString.DefaultSendFaildText, new RaiseEventDelegate<SendFailedEventArgs>(this.RaiseSendFailed));
}
}
}
protected void RaiseConnectFailed(FailedEventArgs argument)
{
EventHandler<FailedEventArgs> connectFailed = this.ConnectFailed;
if (connectFailed != null)
{
connectFailed.Invoke(this, argument);
}
}
private void RaiseRequestReceived(SipRequestReceivedEventArgs argument)
{
EventHandler<SipRequestReceivedEventArgs> requestReceived = this.RequestReceived;
if (requestReceived != null)
{
requestReceived.Invoke(this, argument);
}
}
protected void RaiseSendFailed(SendFailedEventArgs argument)
{
EventHandler<SendFailedEventArgs> sendFailed = this.SendFailed;
if (sendFailed != null)
{
sendFailed.Invoke(this, argument);
}
}
protected void RaiseStateChanged(StateChangedEventArgs argument)
{
EventHandler<StateChangedEventArgs> stateChanged = this.StateChanged;
if (stateChanged != null)
{
stateChanged.Invoke(this, argument);
}
}
private void RaiseWaitTimeoutEvent(SipMessageBase message)
{
if (message is SipInviteResponse)
{
SipMessageHelper.RaiseWaitAckTimeout(message as SipInviteResponse);
}
else if (message is SipRequest)
{
SipMessageHelper.RaiseWaitResponseTimeout(message as SipRequest);
}
}
private void ReceiveMessage(SipcMessage msg)
{
try
{
lock (this._syncObjSendReceive)
{
ClientLogger.WriteSipc("Receive", msg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -