using System; using System.Collections.Concurrent; using TBL.CSharp.Game.Server.Message; using TBL.CSharp.Game.Server.Process; namespace TBL.CSharp.Game.Server; /// /// 服务容器 /// public class ServiceContainer { /// /// 下一个候选服务句柄 /// private int _nextServiceHandle; /// /// 活跃中的服务队列 /// public readonly ConcurrentQueue ActiveSignalQueues; /// /// 服务句柄映射 /// public readonly ConcurrentDictionary ServicesHandleMap; /// /// 工作线程封装组 /// public readonly ConcurrentBag Workers; public ServiceContainer( Func workerProvider, int workerCount ) { workerCount = Math.Max(workerCount, 1); _nextServiceHandle = 0; ActiveSignalQueues = new ConcurrentQueue(); ServicesHandleMap = new ConcurrentDictionary(); Workers = new ConcurrentBag(); for (var i = 0; i < workerCount; i++) { var worker = workerProvider(this); Workers.Add(worker); worker.WorkingThread.Start(); } } /// /// 添加服务 /// public void AddService(Service service) { if (service.Container != null) { throw new Exception($"service {service} already added"); } for (;;) { if (ServicesHandleMap.TryAdd(_nextServiceHandle, service)) { service.Handle = _nextServiceHandle; service.Container = this; break; } if (_nextServiceHandle == int.MaxValue) _nextServiceHandle = 0; else _nextServiceHandle += 1; } } /// /// 解析出服务句柄 /// public int ResolveServiceHandle(string name) { lock (ServicesHandleMap) { foreach (var pair in ServicesHandleMap) { if (name == pair.Value.GetType().FullName) return pair.Key; } } return -1; } /// /// 向指定服务传递信号 /// public void Send(Signal signal) { if (ServicesHandleMap.TryGetValue(signal.TargetAddress.ServiceHandle, out var targetService)) { var queue = targetService.SignalQueue; queue.Enqueue(signal); // 对队列加锁 lock (queue) { // 非活跃的情况下,使其进入活跃序列 if (!queue.ActiveLock) { queue.ActiveLock = true; ActiveSignalQueues.Enqueue(queue); } } } } /// /// 清空 /// public void Clear(bool forceStop = false) { // 工作线程关闭 while (Workers.TryTake(out var worker)) { if (forceStop) worker.WorkingThread.Abort(); else worker.RequestStop(); } } }