123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- using System;
- using Best.HTTP.HostSetting;
- using Best.HTTP.Shared;
- using Best.HTTP.Shared.Logger;
- using Best.HTTP.Shared.PlatformSupport.Threading;
- namespace Best.HTTP.Hosts.Connections
- {
- /// <summary>
- /// Abstract base class for concrete connection implementation (HTTP/1, HTTP/2, WebGL, File).
- /// </summary>
- public abstract class ConnectionBase : IDisposable
- {
- #region Public Properties
- /// <summary>
- /// The address of the server that this connection is bound to.
- /// </summary>
- public HostKey HostKey { get; protected set; }
- /// <summary>
- /// The state of this connection.
- /// </summary>
- public HTTPConnectionStates State { get; internal set; }
- /// <summary>
- /// If the State is HTTPConnectionStates.Processing, then it holds a HTTPRequest instance. Otherwise it's null.
- /// </summary>
- public HTTPRequest CurrentRequest { get; internal set; }
- /// <summary>
- /// How much the connection kept alive after its last request processing.
- /// </summary>
- public virtual TimeSpan KeepAliveTime { get; protected set; }
- public virtual bool CanProcessMultiple { get { return false; } }
- /// <summary>
- /// Number of assigned requests to process.
- /// </summary>
- public virtual int AssignedRequests { get { return this.State != HTTPConnectionStates.Initial && this.State != HTTPConnectionStates.Free ? 1 : 0; } }
- /// <summary>
- /// Maximum number of assignable requests.
- /// </summary>
- public virtual int MaxAssignedRequests { get; } = 1;
- /// <summary>
- /// When we start to process the current request. It's set after the connection is established.
- /// </summary>
- public DateTime StartTime { get; protected set; }
- public Uri LastProcessedUri { get; protected set; }
- public DateTime LastProcessTime { get; protected set; }
- public LoggingContext Context { get; protected set; }
- #endregion
- #region Privates
- protected bool IsThreaded;
- #endregion
- public ConnectionBase(HostKey hostKey)
- :this(hostKey, true)
- {}
- public ConnectionBase(HostKey hostKey, bool threaded)
- {
- this.HostKey = hostKey;
- this.State = HTTPConnectionStates.Initial;
- this.LastProcessTime = HTTPManager.CurrentFrameDateTime; // DateTime.Now;
- // By default we assume an HTTP/1 connection, but in the HTTP-Over-TCP-Connection the request handlers will decide its value.
- this.KeepAliveTime = HTTPManager.PerHostSettings.Get(this.HostKey.Host).HTTP1ConnectionSettings.MaxConnectionIdleTime;
- this.IsThreaded = threaded;
- this.Context = new LoggingContext(this);
- this.Context.Add("HostKey", this.HostKey.ToString());
- }
- internal virtual void Process(HTTPRequest request)
- {
- if (State == HTTPConnectionStates.Processing)
- throw new Exception("Connection already processing a request! " + this.ToString());
- this.State = HTTPConnectionStates.Processing;
- this.CurrentRequest = request;
- this.LastProcessedUri = this.CurrentRequest.CurrentUri;
- if (IsThreaded)
- {
- ThreadedRunner.RunLongLiving(ThreadFunc);
- }
- else
- ThreadFunc();
- }
- protected virtual void ThreadFunc()
- {
- }
- public ShutdownTypes ShutdownType { get; protected set; }
- /// <summary>
- /// Called when the plugin shuts down immediately.
- /// </summary>
- public virtual void Shutdown(ShutdownTypes type)
- {
- this.ShutdownType = type;
- }
-
- #region Dispose Pattern
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- }
- ~ConnectionBase()
- {
- Dispose(false);
- }
- #endregion
- public override string ToString()
- {
- return string.Format("[{0}:{1}]", this.Context.Hash, this.HostKey.ToString());
- }
- }
- }
|