using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Common.Base; using Common.Logger; using Common.Network; using MongoDB.Bson; namespace TNet { public sealed 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() { } private void Dispose(bool disposing) { if (this.acceptor == null) { return; } if (disposing) { foreach (ObjectId id in this.idChannels.Keys.ToArray()) { TChannel channel = this.idChannels[id]; channel.Dispose(); } 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; } public async Task GetChannel() { if (this.acceptor == null) { throw new Exception("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); } private async void SocketConnectAsync(AChannel channel) { while (true) { try { await channel.ConnectAsync(); break; } catch (Exception e) { Log.Trace(e.ToString()); } await this.Timer.Sleep(5000); } } public AChannel GetChannel(string host, int port) { TChannel channel = null; if (this.channels.TryGetValue(host + ":" + port, out channel)) { return channel; } TSocket newSocket = new TSocket(this.poller); channel = new TChannel(newSocket, host, port, this); this.channels[channel.RemoteAddress] = channel; this.idChannels[channel.Id] = channel; this.SocketConnectAsync(channel); return channel; } public AChannel GetChannel(string address) { string[] ss = address.Split(':'); int port = int.Parse(ss[1]); return this.GetChannel(ss[0], port); } public void Update() { this.poller.Update(); this.timerManager.Refresh(); } public TimerManager Timer { get { return this.timerManager; } } } }