ServiceContainer.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System;
  2. using System.Collections.Concurrent;
  3. using TBL.CSharp.Game.Server.Message;
  4. using TBL.CSharp.Game.Server.Process;
  5. namespace TBL.CSharp.Game.Server;
  6. /// <summary>
  7. /// 服务容器
  8. /// </summary>
  9. public class ServiceContainer
  10. {
  11. /// <summary>
  12. /// 下一个候选服务句柄
  13. /// </summary>
  14. private int _nextServiceHandle;
  15. /// <summary>
  16. /// 活跃中的服务队列
  17. /// </summary>
  18. public readonly ConcurrentQueue<SignalQueue> ActiveSignalQueues;
  19. /// <summary>
  20. /// 服务句柄映射
  21. /// </summary>
  22. public readonly ConcurrentDictionary<int, Service> ServicesHandleMap;
  23. /// <summary>
  24. /// 工作线程封装组
  25. /// </summary>
  26. public readonly ConcurrentBag<Worker> Workers;
  27. public ServiceContainer(
  28. Func<ServiceContainer, Worker> workerProvider,
  29. int workerCount
  30. )
  31. {
  32. workerCount = Math.Max(workerCount, 1);
  33. _nextServiceHandle = 0;
  34. ActiveSignalQueues = new ConcurrentQueue<SignalQueue>();
  35. ServicesHandleMap = new ConcurrentDictionary<int, Service>();
  36. Workers = new ConcurrentBag<Worker>();
  37. for (var i = 0; i < workerCount; i++)
  38. {
  39. var worker = workerProvider(this);
  40. Workers.Add(worker);
  41. worker.WorkingThread.Start();
  42. }
  43. }
  44. /// <summary>
  45. /// 添加服务
  46. /// </summary>
  47. public void AddService(Service service)
  48. {
  49. if (service.Container != null)
  50. {
  51. throw new Exception($"service {service} already added");
  52. }
  53. for (;;)
  54. {
  55. if (ServicesHandleMap.TryAdd(_nextServiceHandle, service))
  56. {
  57. service.Handle = _nextServiceHandle;
  58. service.Container = this;
  59. break;
  60. }
  61. if (_nextServiceHandle == int.MaxValue)
  62. _nextServiceHandle = 0;
  63. else
  64. _nextServiceHandle += 1;
  65. }
  66. }
  67. /// <summary>
  68. /// 解析出服务句柄
  69. /// </summary>
  70. public int ResolveServiceHandle(string name)
  71. {
  72. lock (ServicesHandleMap)
  73. {
  74. foreach (var pair in ServicesHandleMap)
  75. {
  76. if (name == pair.Value.GetType().FullName)
  77. return pair.Key;
  78. }
  79. }
  80. return -1;
  81. }
  82. /// <summary>
  83. /// 向指定服务传递信号
  84. /// </summary>
  85. public void Send(Signal signal)
  86. {
  87. if (ServicesHandleMap.TryGetValue(signal.TargetAddress.ServiceHandle, out var targetService))
  88. {
  89. var queue = targetService.SignalQueue;
  90. queue.Enqueue(signal);
  91. // 对队列加锁
  92. lock (queue)
  93. {
  94. // 非活跃的情况下,使其进入活跃序列
  95. if (!queue.ActiveLock)
  96. {
  97. queue.ActiveLock = true;
  98. ActiveSignalQueues.Enqueue(queue);
  99. }
  100. }
  101. }
  102. }
  103. /// <summary>
  104. /// 清空
  105. /// </summary>
  106. public void Clear(bool forceStop = false)
  107. {
  108. // 工作线程关闭
  109. while (Workers.TryTake(out var worker))
  110. {
  111. if (forceStop)
  112. worker.WorkingThread.Abort();
  113. else
  114. worker.RequestStop();
  115. }
  116. }
  117. }