📄 httpsipconnection.cs
字号:
namespace Imps.Client.CommLayer.HttpSipConnection
{
using Imps.Base.Sipc;
using Imps.Client.Base;
using Imps.Client.Base.Comm;
using Imps.Client.CommLayer;
using Imps.Client.CommLayer.Common;
using Imps.Client.Resource;
using Imps.Client.Utils;
using Imps.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
internal sealed class HttpSipConnection : SipConnectionBase
{
private byte[] _Buffer;
private static long _CSeqNumber = 0;
private volatile int _CurTimeSpan;
private static readonly byte[] _EndOfMessage = Encoding.UTF8.GetBytes("SIPP");
private IPEndPoint _IpEndPoint;
private object _IpEndPointLocker;
private int _MaxPeriod;
private const int _MaxRequestPeriod = 0x3a98;
private int _MinPeriod;
private const int _MinRequestPeriod = 500;
private const int _NormalRequestPeriod = 0x7d0;
private volatile bool _peekedMessageFlag;
private string _Pragma;
private DateTime _RefTime;
private Queue<SipMessageBase>[] _SendingMessageList;
private readonly SendWindow _sendWindow;
private object _syncLockClose;
private object _syncLockPeekedMessageFlag;
private object _syncLockRunningProc;
private Timer _Timer;
private const int _TimerBufferSize = 10;
private IWebProxy _WebProxy;
private const int MaxTryTimes = 5;
public event EventHandler<FailedEventArgs> ConnectFailed;
public event EventHandler<SendFailedEventArgs> SendFailed;
public HttpSipConnection(object context, HttpSipConnectionOption option) : base(context)
{
this._IpEndPointLocker = new object();
this._syncLockClose = new object();
this._SendingMessageList = new Queue<SipMessageBase>[] { new Queue<SipMessageBase>(), new Queue<SipMessageBase>() };
this._syncLockPeekedMessageFlag = new object();
this._Buffer = new byte[0x400];
this._syncLockRunningProc = new object();
this._peekedMessageFlag = true;
this._sendWindow = new SendWindow(0xea60, 100);
this._MinPeriod = 0x7d0;
this._MaxPeriod = 0x3a98;
this._RefTime = DateTime.MinValue;
this._CurTimeSpan = 0x7d0;
base.Option = option;
base.StateChanged += new EventHandler<StateChangedEventArgs>(this, (IntPtr) this.HttpSipConnection_StateChanged);
}
private void _SendMessage(string url, byte[] buffer, int maxTryTimes)
{
int num = 1;
while (true)
{
MemoryStream stream = null;
SipcLogHelper helper = null;
byte[] bytes = null;
try
{
HttpWebRequest request = this.CreateHttpWebRequest(url);
request.Timeout = 0x9c40;
if (ClientLogger.Logger.IsLogConnection)
{
stream = new MemoryStream(0x800);
bytes = Encoding.UTF8.GetBytes("\r\n");
helper = new SipcLogHelper();
}
using (Stream stream2 = request.GetRequestStream())
{
if (buffer != null)
{
stream2.Write(buffer, 0, buffer.Length);
}
stream2.Write(_EndOfMessage, 0, _EndOfMessage.Length);
if (stream != null)
{
byte[] buffer3 = Encoding.UTF8.GetBytes(url);
stream.Write(buffer3, 0, buffer3.Length);
stream.Write(bytes, 0, bytes.Length);
byte[] buffer4 = request.Headers.ToByteArray();
stream.Write(buffer4, 0, buffer4.Length);
stream.Write(bytes, 0, bytes.Length);
string detail = string.Empty;
if (buffer != null)
{
helper.Parse(buffer, 0, buffer.Length);
detail = Encoding.UTF8.GetString(stream.ToArray()) + helper.ToString() + Encoding.UTF8.GetString(_EndOfMessage);
}
else
{
stream.Write(_EndOfMessage, 0, _EndOfMessage.Length);
detail = Encoding.UTF8.GetString(stream.ToArray());
}
ClientLogger.WriteConnection("Send", 0, detail, 0);
stream.Seek((long) 0, SeekOrigin.Begin);
stream.SetLength((long) 0);
helper.Clear();
}
}
using (HttpWebResponse response = ((HttpWebResponse) request.GetResponse()))
{
int num2 = ((int) response.ContentLength) - _EndOfMessage.Length;
if (stream != null)
{
byte[] buffer5 = response.Headers.ToByteArray();
stream.Write(buffer5, 0, buffer5.Length);
stream.Write(bytes, 0, bytes.Length);
}
if (num2 > 0)
{
using (Stream stream3 = response.GetResponseStream())
{
int count;
while ((count = stream3.Read(this._Buffer, 0, Math.Min(num2, this._Buffer.Length))) > 0)
{
base.ParseMessage(this._Buffer, 0, count);
num2 -= count;
if (stream != null)
{
helper.Parse(this._Buffer, 0, count);
}
}
}
}
if (stream != null)
{
string text2 = Encoding.UTF8.GetString(stream.ToArray()) + helper.ToString() + Encoding.UTF8.GetString(_EndOfMessage);
ClientLogger.WriteConnection("Receive", 0, text2, 0);
}
}
return;
}
catch (WebException exception)
{
base.LogError(exception);
HttpWebResponse response2 = exception.Response as HttpWebResponse;
if (response2 != null)
{
switch (response2.StatusCode)
{
case HttpStatusCode.Unauthorized:
throw new SipConnectionException(StringTable.User.SsiCredentialExpired, exception);
case HttpStatusCode.PaymentRequired:
case HttpStatusCode.Forbidden:
goto Label_032A;
case HttpStatusCode.NotFound:
throw new SipConnectionException(StringTable.MsgLoginServiceClosed, exception);
case HttpStatusCode.MethodNotAllowed:
throw new SipConnectionException("连接已被重置", exception);
}
}
else if ((num >= maxTryTimes) && (((exception.Status == WebExceptionStatus.ConnectFailure) || (exception.Status == WebExceptionStatus.NameResolutionFailure)) || (exception.Status == WebExceptionStatus.ProxyNameResolutionFailure)))
{
SipConnectionException exception2 = new SipConnectionException(string.Empty, exception);
exception2.Status = SipStatus.SkipRetry;
throw exception2;
}
Label_032A:
if (num >= maxTryTimes)
{
throw new SipConnectionException(string.Empty, exception);
}
Thread.Sleep(0x7d0);
}
catch (Exception exception3)
{
base.LogError(exception3);
throw;
}
num++;
}
}
private void AppendMessageItem(SipMessageBase msg)
{
lock (this._SendingMessageList)
{
if ((msg is SipResponse) || (msg is SipAckRequest))
{
this._SendingMessageList[0].Enqueue(msg);
}
else
{
this._SendingMessageList[1].Enqueue(msg);
}
}
}
private void BeginSendMessage(string uri)
{
try
{
this._SendMessage(uri, null, 5);
base.State = ConnectionState.Connected;
}
catch (Exception exception)
{
base.State = ConnectionState.Disconnected;
base.LogError(exception);
base.RaiseConnectFailed(new FailedEventArgs(exception));
}
}
private void ClearMessageItem()
{
lock (this._SendingMessageList)
{
foreach (Queue<SipMessageBase> queue in this._SendingMessageList)
{
queue.Clear();
}
}
}
public override void Close()
{
WaitCallback callBack = null;
if (base.State == ConnectionState.Connected)
{
lock (this._syncLockClose)
{
if (base.State == ConnectionState.Connected)
{
base.Close();
this.RaiseAllMessageSendFaild();
this.ClearMessageItem();
if (callBack == null)
{
callBack = delegate {
try
{
base.State = ConnectionState.Disconnecting;
this.CloseTimer();
HttpWebRequest request = this.CreateHttpWebRequest(this.Option.HttpTurnal + "?t=d&i=" + GetNextCSeqNumber());
request.ContentLength = 0;
((HttpWebResponse) request.GetResponse()).Close();
}
catch (Exception)
{
}
finally
{
base.State = ConnectionState.Disconnected;
}
};
}
ThreadPool.QueueUserWorkItem(callBack);
}
}
}
}
private void CloseTimer()
{
if (this._Timer != null)
{
this._Timer.Change(-1, -1);
this._Timer.Dispose();
this._Timer = null;
}
}
public override void Connect(string host, int port)
{
this.WriteConnectionLog();
base.State = ConnectionState.Connecting;
this._Pragma = "xz4BBcV" + Guid.NewGuid().ToString();
try
{
if (string.IsNullOrEmpty(this.Option.HttpTurnal))
{
throw new ArgumentNullException("HttpTurnal");
}
string uri = this.Option.HttpTurnal + "?t=i&i=" + GetNextCSeqNumber();
new AsyncBeginHttpRequest(this.BeginSendMessage).BeginInvoke(uri, new AsyncCallback(this.EndSendMessage), this);
}
catch (Exception exception)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -