using System; using System.Collections.Generic; using System.Threading.Tasks; using Common.Base; using Common.Network; using MongoDB.Bson; namespace TNet { public class TService: IService { private readonly IPoller poller = new TPoller(); private TSocket acceptor; private readonly Dictionary channels = new Dictionary(); private readonly Dictionary idChannels = new Dictionary(); private readonly TimerManager timerManager = new TimerManager(); /// /// 即可做client也可做server /// /// /// public TService(string host, int port) { this.acceptor = new TSocket(this.poller); this.acceptor.Bind(host, port); this.acceptor.Listen(100); } /// /// 只能做client端的构造函数 /// public TService() { } protected virtual void Dispose(bool disposing) { if (this.acceptor == null) { return; } if (disposing) { this.acceptor.Dispose(); } this.acceptor = null; } ~TService() { this.Dispose(false); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } public void Add(Action action) { this.poller.Add(action); } public AChannel GetChannel(ObjectId id) { TChannel channel = null; this.idChannels.TryGetValue(id, out channel); return channel; } private async Task ConnectAsync(string host, int port) { TSocket newSocket = new TSocket(this.poller); await newSocket.ConnectAsync(host, port); TChannel channel = new TChannel(newSocket, this); this.channels[newSocket.RemoteAddress] = channel; this.idChannels[channel.Id] = channel; return channel; } public async Task GetChannel() { if (this.acceptor == null) { throw new Exception(string.Format("service construct must use host and port param")); } TSocket socket = new TSocket(this.poller); await this.acceptor.AcceptAsync(socket); TChannel channel = new TChannel(socket, this); this.channels[channel.RemoteAddress] = channel; this.idChannels[channel.Id] = channel; return channel; } public void Remove(AChannel channel) { TChannel tChannel = channel as TChannel; if (tChannel == null) { return; } this.idChannels.Remove(channel.Id); this.channels.Remove(channel.RemoteAddress); this.timerManager.Remove(tChannel.SendTimer); } public async Task GetChannel(string host, int port) { TChannel channel = null; if (this.channels.TryGetValue(host + ":" + port, out channel)) { return channel; } return await this.ConnectAsync(host, port); } public void RunOnce(int timeout) { this.poller.Run(timeout); } public void Run() { while (true) { this.RunOnce(1); this.timerManager.Refresh(); } } internal TimerManager Timer { get { return this.timerManager; } } } }