您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

227 行
7.2 KiB

  1. using JT1078.Gateway.Extensions;
  2. using JT1078.Gateway.Metadata;
  3. using Microsoft.Extensions.Logging;
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Net.WebSockets;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. namespace JT1078.Gateway.Sessions
  14. {
  15. public class JT1078HttpSessionManager
  16. {
  17. public ConcurrentDictionary<string, JT1078HttpContext> Sessions { get; }
  18. private ILogger Logger;
  19. public JT1078HttpSessionManager(ILoggerFactory loggerFactory)
  20. {
  21. Sessions = new ConcurrentDictionary<string, JT1078HttpContext>();
  22. Logger = loggerFactory.CreateLogger<JT1078HttpSessionManager>();
  23. }
  24. public bool TryAdd(JT1078HttpContext httpContext)
  25. {
  26. return Sessions.TryAdd(httpContext.SessionId, httpContext);
  27. }
  28. public void AddOrUpdateHlsSession(JT1078HttpContext httpContext)
  29. {
  30. //如果不存在就添加,如果存在则删除后添加(保持key和value中的sessionid一致)
  31. var session = Sessions.FirstOrDefault(m => m.Value.Sim == httpContext.Sim && m.Value.ChannelNo == httpContext.ChannelNo && m.Value.RTPVideoType == RTPVideoType.Http_Hls);
  32. if (!string.IsNullOrEmpty(session.Key))
  33. {
  34. Sessions.TryRemove(session.Key, out var _);
  35. }
  36. Sessions.TryAdd(httpContext.SessionId, httpContext);
  37. }
  38. public async void TryRemove(string sessionId)
  39. {
  40. if(Sessions.TryRemove(sessionId, out JT1078HttpContext session))
  41. {
  42. try
  43. {
  44. if (session.IsWebSocket)
  45. {
  46. await session.WebSocketClose("close");
  47. }
  48. else
  49. {
  50. await session.HttpClose();
  51. }
  52. }
  53. catch (Exception)
  54. {
  55. }
  56. }
  57. }
  58. public async void TryRemoveBySim(string sim)
  59. {
  60. var keys=Sessions.Where(f => f.Value.Sim == sim).Select(s => s.Key);
  61. foreach(var key in keys)
  62. {
  63. if (Sessions.TryRemove(key, out JT1078HttpContext session))
  64. {
  65. try
  66. {
  67. if (session.IsWebSocket)
  68. {
  69. await session.WebSocketClose("close");
  70. }
  71. else
  72. {
  73. await session.HttpClose();
  74. }
  75. }
  76. catch (Exception)
  77. {
  78. }
  79. }
  80. }
  81. }
  82. private void remove(string sessionId)
  83. {
  84. if (Sessions.TryRemove(sessionId, out JT1078HttpContext session))
  85. {
  86. }
  87. }
  88. /// <summary>
  89. /// 发送音视频数据
  90. /// </summary>
  91. /// <param name="httpContext"></param>
  92. /// <param name="data"></param>
  93. /// <param name="firstSend"></param>
  94. public async void SendAVData(JT1078HttpContext httpContext, byte[] data, bool firstSend)
  95. {
  96. if (httpContext.IsWebSocket)
  97. {
  98. if (firstSend)
  99. {
  100. httpContext.FirstSend = firstSend;
  101. Sessions.TryUpdate(httpContext.SessionId, httpContext, httpContext);
  102. }
  103. try
  104. {
  105. await httpContext.WebSocketSendBinaryAsync(data);
  106. }
  107. catch (Exception ex)
  108. {
  109. if (Logger.IsEnabled(LogLevel.Information))
  110. {
  111. Logger.LogInformation($"[ws close]:{httpContext.SessionId}-{httpContext.Sim}-{httpContext.ChannelNo}-{httpContext.StartTime:yyyyMMddhhmmss}");
  112. }
  113. remove(httpContext.SessionId);
  114. }
  115. }
  116. else
  117. {
  118. if (firstSend)
  119. {
  120. httpContext.FirstSend = firstSend;
  121. Sessions.TryUpdate(httpContext.SessionId, httpContext, httpContext);
  122. try
  123. {
  124. await httpContext.HttpSendFirstChunked(data);
  125. }
  126. catch (Exception ex)
  127. {
  128. if (Logger.IsEnabled(LogLevel.Information))
  129. {
  130. Logger.LogInformation($"[http close]:{httpContext.SessionId}-{httpContext.Sim}-{httpContext.ChannelNo}-{httpContext.StartTime:yyyyMMddhhmmss}");
  131. }
  132. remove(httpContext.SessionId);
  133. }
  134. }
  135. else
  136. {
  137. try
  138. {
  139. await httpContext.HttpSendChunked(data);
  140. }
  141. catch (Exception ex)
  142. {
  143. if (Logger.IsEnabled(LogLevel.Information))
  144. {
  145. Logger.LogInformation($"[http close]:{httpContext.SessionId}-{httpContext.Sim}-{httpContext.ChannelNo}-{httpContext.StartTime:yyyyMMddhhmmss}");
  146. }
  147. remove(httpContext.SessionId);
  148. }
  149. }
  150. }
  151. }
  152. public int SessionCount
  153. {
  154. get
  155. {
  156. return Sessions.Count;
  157. }
  158. }
  159. public int HttpSessionCount
  160. {
  161. get
  162. {
  163. return Sessions.Count(c=>!c.Value.IsWebSocket);
  164. }
  165. }
  166. public int WebSocketSessionCount
  167. {
  168. get
  169. {
  170. return Sessions.Count(c => c.Value.IsWebSocket);
  171. }
  172. }
  173. public List<JT1078HttpContext> GetAllBySimAndChannelNo(string sim, int channelNo)
  174. {
  175. return Sessions.Select(s => s.Value).Where(w => w.Sim == sim && w.ChannelNo == channelNo).ToList();
  176. }
  177. public List<JT1078HttpContext> GetAllHttpContextBySimAndChannelNo(string sim, int channelNo)
  178. {
  179. return Sessions.Select(s => s.Value).Where(w => w.Sim == sim && w.ChannelNo == channelNo&&!w.IsWebSocket).ToList();
  180. }
  181. public List<JT1078HttpContext> GetAll()
  182. {
  183. return Sessions.Select(s => s.Value).ToList();
  184. }
  185. internal void TryRemoveAll()
  186. {
  187. foreach(var item in Sessions)
  188. {
  189. try
  190. {
  191. if (item.Value.IsWebSocket)
  192. {
  193. item.Value.WebSocketContext.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "server close", CancellationToken.None);
  194. }
  195. else
  196. {
  197. item.Value.Context.Response.Close();
  198. }
  199. }
  200. catch (Exception)
  201. {
  202. }
  203. }
  204. }
  205. }
  206. }