using System; using System.Collections.Generic; using System.IO; using System.Net; namespace ET { public abstract class AService : IDisposable { public Action AcceptCallback; public Action ReadCallback; public Action ErrorCallback; public long Id { get; set; } = IdGenerater.Instance.GenerateId(); public ServiceType ServiceType { get; protected set; } private const int MaxMemoryBufferSize = 1024; private readonly Queue pool = new Queue(); public MemoryStream Fetch(int size = 0) { if (size > MaxMemoryBufferSize) { return new MemoryStream(size); } if (size < MaxMemoryBufferSize) { size = MaxMemoryBufferSize; } if (this.pool.Count == 0) { return new MemoryStream(size); } return pool.Dequeue(); } public void OnError(long channelId, int e) { this.Remove(channelId); this.ErrorCallback?.Invoke(channelId, e); } public void Recycle(MemoryStream memoryBuffer) { if (memoryBuffer.Capacity > 1024) { return; } if (this.pool.Count > 10) // 这里不需要太大,其实Kcp跟Tcp,这里1就足够了 { return; } memoryBuffer.Seek(0, SeekOrigin.Begin); memoryBuffer.SetLength(0); this.pool.Enqueue(memoryBuffer); } // public virtual void Dispose() // { // this.Id = 0; // } public abstract void Dispose(); public abstract void Update(); public abstract void Remove(long id, int error = 0); public abstract bool IsDisposed(); // public bool IsDisposed() // { // return this.Id == 0; // } public abstract void Create(long id, IPEndPoint ipEndPoint, string address); //public abstract void Send(long channelId, MemoryStream memoryBuffer); public abstract void Send(long channelId, long actorId, MemoryStream stream); public virtual (uint, uint) GetChannelConn(long channelId) { throw new Exception($"default conn throw Exception! {channelId}"); } public virtual void ChangeAddress(long channelId, IPEndPoint ipEndPoint) { } // localConn放在低32bit private long acceptIdGenerater = 1; public long CreateAcceptChannelId(uint localConn) { return (++this.acceptIdGenerater << 32) | localConn; } // localConn放在低32bit private long connectIdGenerater = int.MaxValue; public long CreateConnectChannelId(uint localConn) { return (--this.connectIdGenerater << 32) | localConn; } public uint CreateRandomLocalConn() { return (1u << 30) | RandomHelper.RandUInt32(); } protected void OnAccept(long channelId, IPEndPoint ipEndPoint) { this.AcceptCallback.Invoke(channelId, ipEndPoint); } } }