关键词搜索

源码搜索 ×
×

C# 开启HTTP监听服务与线程数量控制

发布2018-07-14浏览2302次

详情内容

如何开IP和端口的HTTP监听这里就是按照实现这种方式来加以说明,另外线程不要再循环里面不停的new Thread()这样很耗性能。

开启HTTP服务监听
  1. /// <summary>
  2. /// 启动HttpService监听
  3. /// </summary>
  4. /// <param name="MyTask"></param>
  5. /// <returns></returns>
  6. public bool Start(Task MyTask)
  7. {
  8. this.MyTask = MyTask;
  9. if (!HttpListener.IsSupported)
  10. {
  11. SQ.Base.ErrorLog.WriteLog4("GovernmentHttpService::Start() HttpListener not support !", SQ.Base.LOGTYPE.ERRORD);
  12. return false;
  13. }
  14. if (m_http_thread != null)
  15. return true;
  16. string http_url = "http://" + MyTask.Config.GovWebIp + ":" + MyTask.Config.GovPort + "/";
  17. try
  18. {
  19. m_http_listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
  20. m_http_listener.Prefixes.Add(http_url);
  21. m_http_listener.Start();
  22. m_http_thread = new Thread(HttpServiceThd);
  23. m_http_thread.Name = "HttpServiceThd";
  24. m_http_thread.IsBackground = true;
  25. m_http_thread.Start();
  26. m_service_thread = new Thread(ServiceThd);
  27. m_service_thread.Name = "ServiceThd";
  28. m_service_thread.IsBackground = true;
  29. m_service_thread.Start();
  30. }
  31. catch (Exception ex)
  32. {
  33. SQ.Base.ErrorLog.WriteLog4Ex("GovernmentHttpService::Start " + http_url + " ", ex);
  34. }
  35. return false;
  36. }
  37. /// <summary>
  38. /// 线程处理http请求方法
  39. /// </summary>
  40. protected virtual void HttpServiceThd()
  41. {
  42. while (true)
  43. {
  44. try
  45. {
  46. HttpListenerContext context = m_http_listener.GetContext();
  47. HttpListenerRequest request = context.Request;
  48. HttpListenerResponse response = context.Response;
  49. var param = request.Url.ToString();
  50. // 解码ASCII参数
  51. // param = HttpDataParser.ASCII2Str(param);
  52. // 解码UTF8参数
  53. param = Encoding.UTF8.GetString(Encoding.Default.GetBytes(param.ToString()));
  54. Log.WriteLog4("上级平台请求:>>>>>>>>>>>>>>>" + param);
  55. int index = param.LastIndexOf("/");
  56. param = param.Substring(index, param.Length - index);
  57. // 替换"/"
  58. param = param.Replace("/", "");
  59. // 预解析
  60. HttpDataParser.Validator preValidator = new HttpDataParser.Validator(MyTask);
  61. if (preValidator.PreParse(param))
  62. {
  63. //验证通过之后调用接口复用或者建立连接传输流数据
  64. //validator.Sim,validator.Channel,validator.DataType;
  65. //redis key:车牌号码.车牌颜色.逻辑道通号.音视频标志
  66. //实时 real@json; 回放 back@json ;实时控制 realCtrl@json;
  67. HttpDataParser.Validator validator = HttpDataParser.Parse(MyTask, param);
  68. bool status = validator.GetStatus();
  69. if (status)
  70. {
  71. Service service = new Service();
  72. service.Context = context;
  73. service.Validator = validator;
  74. string key = validator.PlateCode + "." + validator.PlateColor + "." + validator.Channel + "." + validator.DataType;
  75. dictionaryService.Add(key, service);
  76. dictionaryTime.Add(key, DateTime.Now);
  77. }
  78. else
  79. {
  80. // 未通过解析
  81. response.StatusCode = 300;
  82. response.Close();
  83. }
  84. }
  85. else
  86. {
  87. // 未通过预解析
  88. response.StatusCode = 300;
  89. response.Close();
  90. }
  91. }
  92. catch (Exception ex)
  93. {
  94. SQ.Base.ErrorLog.WriteLog4Ex("上级平台请求HTTP流服务->GovernmentHttpService:HttpServiceThd", ex);
  95. }
  96. }
  97. }

启动start方法即可。

控制线程数量

控制线程的数量可以有效提高系统性能,最简单的方式就是开启一个线程来处理一类业务,将自己的需要处理的加到一个集合中用线程去处理:

  1. Service service = new Service();
  2. service.Context = context;
  3. service.Validator = validator;
  4. string key = validator.PlateCode + "." + validator.PlateColor + "." + validator.Channel + "." + validator.DataType;
  5. dictionaryService.Add(key, service);
  6. dictionaryTime.Add(key, DateTime.Now);

执行业务处理:

  1. class Service
  2. {
  3. public HttpListenerContext Context { set; get; }
  4. public HttpDataParser.Validator Validator { set; get; }
  5. }
  6. /// <summary>
  7. /// 业务线程执行方法
  8. /// </summary>
  9. void ServiceThd()
  10. {
  11. while (true)
  12. {
  13. try
  14. {
  15. TimeSpan timeSpan;
  16. foreach (var item in dictionaryService.ToList())
  17. {
  18. DateTime startTime;
  19. dictionaryTime.TryGetValue(item.Key, out startTime);
  20. timeSpan = DateTime.Now - startTime;
  21. if (timeSpan.Seconds < 5)
  22. {
  23. bool flag = ServiceProcess(item.Value.Context, item.Value.Validator);
  24. if (flag)
  25. {
  26. dictionaryService.Remove(item.Key);
  27. dictionaryTime.Remove(item.Key);
  28. }
  29. }
  30. else
  31. {
  32. dictionaryService.Remove(item.Key);
  33. dictionaryTime.Remove(item.Key);
  34. }
  35. }
  36. Thread.Sleep(1000);
  37. }
  38. catch (Exception ex)
  39. {
  40. SQ.Base.ErrorLog.WriteLog4Ex("上级平台业务处理线程执行GovernmentHttpService:ServiceThd",ex);
  41. }
  42. }
  43. }
  44. /// <summary>
  45. /// 执行业务处理方法
  46. /// </summary>
  47. /// <param name="context"></param>
  48. /// <param name="validator"></param>
  49. bool ServiceProcess(HttpListenerContext context,HttpDataParser.Validator validator)
  50. {
  51. try
  52. {
  53. string key = validator.PlateCode + "." + validator.PlateColor + "." + validator.Channel + "." + validator.DataType;
  54. string result = HttpDataParser.GetRedisData(key);
  55. if (!string.IsNullOrEmpty(result) && result.Contains("@"))
  56. {
  57. SQ.Base.Log.WriteLog4("上级平台业务处理Get data from redis:result=" + result);
  58. string[] strs = result.Split('@');
  59. var type = strs[0];
  60. var json = strs[1];
  61. if ("real".Equals(type))
  62. {
  63. // 实时视频
  64. JTSDownRealVideoRequest jtSDownRealVideoRequest = json.ParseJSON<JTSDownRealVideoRequest>();
  65. GovernmentWebClientManage.AcceptRealConnect(context, key, validator.Sim, (byte)validator.Channel, (byte)validator.DataType);
  66. return true;
  67. }
  68. else if ("back".Equals(type))
  69. {
  70. // 回放视频
  71. JTRTDownPlayBackMsgStartUp jtRTDownPlayBackMsgStartUp = json.ParseJSON<JTRTDownPlayBackMsgStartUp>();
  72. GovernmentWebClientManage.AcceptBackConnect(context, key, validator.Sim, (byte)validator.Channel, jtRTDownPlayBackMsgStartUp.PLAYBACK_STARTTIME.UNIXtoDateTime(), (long)jtRTDownPlayBackMsgStartUp.PLAYBACK_ENDTIME, (AudioVideoFlag)validator.DataType);
  73. return true;
  74. }
  75. }
  76. else
  77. {
  78. SQ.Base.Log.WriteLog4("上级平台业务处理Get data from redis:result="+result);
  79. }
  80. }
  81. catch (Exception ex)
  82. {
  83. SQ.Base.ErrorLog.WriteLog4Ex("上级平台业务处理ServiceProcess read data from redis:", ex);
  84. }
  85. return false;
  86. }

这里我们应该注意到,我们会启动这个线程,前面HTTP服务启动中有,代码如下:

  1. m_service_thread = new Thread(ServiceThd);
  2. m_service_thread.Name = "ServiceThd";
  3. m_service_thread.IsBackground = true;
  4. m_service_thread.Start();
注意:代码的规范性和简洁,才能保证优质的服务。

 要记得操作List和Dictionary加锁,以下是示例代码:

  1. using JT1078Server.Client.GovWebClient;
  2. using JX;
  3. using SQ.Base;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. namespace JT1078Server.Client.GovWeb
  13. {
  14. /// <summary>
  15. /// 上级政府平台HTTP请求流监听服务
  16. /// </summary>
  17. public class GovernmentHttpService
  18. {
  19. private HttpListener m_http_listener = new HttpListener();
  20. private Thread m_http_thread = null;
  21. private Thread m_service_thread = null;
  22. private Dictionary<string, DateTime> dictionaryTime = new Dictionary<string, DateTime>();
  23. private Dictionary<string, Service> dictionaryService = new Dictionary<string, Service>();
  24. Task MyTask=null;
  25. object obj = new object();
  26. /// <summary>
  27. /// 启动HttpService监听
  28. /// </summary>
  29. /// <param name="MyTask"></param>
  30. /// <returns></returns>
  31. public bool Start(Task MyTask)
  32. {
  33. this.MyTask = MyTask;
  34. if (!HttpListener.IsSupported)
  35. {
  36. SQ.Base.ErrorLog.WriteLog4("GovernmentHttpService::Start() HttpListener not support !", SQ.Base.LOGTYPE.ERRORD);
  37. return false;
  38. }
  39. if (m_http_thread != null)
  40. return true;
  41. string http_url = "http://" + MyTask.Config.GovWebIp + ":" + MyTask.Config.GovPort + "/";
  42. try
  43. {
  44. m_http_listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
  45. m_http_listener.Prefixes.Add(http_url);
  46. m_http_listener.Start();
  47. m_http_thread = new Thread(HttpServiceThd);
  48. m_http_thread.Name = "HttpServiceThd";
  49. m_http_thread.IsBackground = true;
  50. m_http_thread.Start();
  51. m_service_thread = new Thread(ServiceThd);
  52. m_service_thread.Name = "ServiceThd";
  53. m_service_thread.IsBackground = true;
  54. m_service_thread.Start();
  55. }
  56. catch (Exception ex)
  57. {
  58. SQ.Base.ErrorLog.WriteLog4Ex("GovernmentHttpService::Start " + http_url + " ", ex);
  59. }
  60. return false;
  61. }
  62. /// <summary>
  63. /// 线程处理http请求方法
  64. /// </summary>
  65. protected virtual void HttpServiceThd()
  66. {
  67. while (true)
  68. {
  69. try
  70. {
  71. HttpListenerContext context = m_http_listener.GetContext();
  72. HttpListenerRequest request = context.Request;
  73. HttpListenerResponse response = context.Response;
  74. var param = request.Url.ToString();
  75. Log.WriteLog4("上级平台原始请求:>>>>>>>>>>>>>>>" + param);
  76. param= System.Web.HttpUtility.UrlDecode(param, Encoding.UTF8);
  77. Log.WriteLog4("上级平台解码请求:>>>>>>>>>>>>>>>" + param);
  78. // 解码ASCII参数
  79. // param = HttpDataParser.ASCII2Str(param);
  80. //if(true)
  81. //{
  82. // GovernmentWebClientManage.AcceptRealConnect(context, "123", "013777882100", 1, 0);
  83. //}
  84. //continue;
  85. // 解码ASCII参数
  86. // param = HttpDataParser.ASCII2Str(param);
  87. 解码UTF8参数
  88. //param = Encoding.UTF8.GetString(Encoding.Default.GetBytes(param.ToString()));
  89. int index = param.LastIndexOf("/");
  90. param = param.Substring(index, param.Length - index);
  91. // 替换"/"
  92. param = param.Replace("/", "");
  93. // 预解析
  94. HttpDataParser.Validator preValidator = new HttpDataParser.Validator(MyTask);
  95. if (preValidator.PreParse(param))
  96. {
  97. //验证通过之后调用接口复用或者建立连接传输流数据
  98. //validator.Sim,validator.Channel,validator.DataType;
  99. //redis key:车牌号码.车牌颜色.逻辑道通号.音视频标志
  100. //实时 real@json; 回放 back@json ;实时控制 realCtrl@json;
  101. HttpDataParser.Validator validator = HttpDataParser.Parse(MyTask, param);
  102. bool status = validator.GetStatus();
  103. if (status)
  104. {
  105. Service service = new Service();
  106. service.Context = context;
  107. service.Validator = validator;
  108. string key = validator.PlateCode + "." + validator.PlateColor + "." + validator.Channel + "." + validator.DataType;
  109. // 添加到处理列表
  110. lock (obj)
  111. {
  112. if (dictionaryService.ContainsKey(key))
  113. {
  114. dictionaryService[key] = service;
  115. dictionaryTime[key] = DateTime.Now;
  116. }
  117. else
  118. {
  119. dictionaryService.Add(key, service);
  120. dictionaryTime.Add(key, DateTime.Now);
  121. }
  122. }
  123. }
  124. else
  125. {
  126. // 未通过解析
  127. response.StatusCode = 300;
  128. response.Close();
  129. }
  130. }
  131. else
  132. {
  133. // 未通过预解析
  134. response.StatusCode = 300;
  135. response.Close();
  136. }
  137. }
  138. catch (Exception ex)
  139. {
  140. SQ.Base.ErrorLog.WriteLog4Ex("上级平台请求HTTP流服务->GovernmentHttpService:HttpServiceThd", ex);
  141. }
  142. }
  143. }
  144. class Service
  145. {
  146. public HttpListenerContext Context { set; get; }
  147. public HttpDataParser.Validator Validator { set; get; }
  148. }
  149. /// <summary>
  150. /// 业务线程执行方法
  151. /// </summary>
  152. void ServiceThd()
  153. {
  154. while (true)
  155. {
  156. try
  157. {
  158. TimeSpan timeSpan;
  159. foreach (var item in dictionaryService.ToList())
  160. {
  161. DateTime startTime;
  162. dictionaryTime.TryGetValue(item.Key, out startTime);
  163. timeSpan = DateTime.Now - startTime;
  164. if (timeSpan.Seconds < 5)
  165. {
  166. bool flag = ServiceProcess(item.Value.Context, item.Value.Validator);
  167. if (flag)
  168. {
  169. lock(obj)
  170. {
  171. dictionaryService.Remove(item.Key);
  172. dictionaryTime.Remove(item.Key);
  173. }
  174. }
  175. }
  176. else
  177. {
  178. lock(obj)
  179. {
  180. dictionaryService.Remove(item.Key);
  181. dictionaryTime.Remove(item.Key);
  182. }
  183. }
  184. }
  185. Thread.Sleep(1000);
  186. }
  187. catch (Exception ex)
  188. {
  189. SQ.Base.ErrorLog.WriteLog4Ex("上级平台业务处理线程执行GovernmentHttpService:ServiceThd",ex);
  190. }
  191. }
  192. }
  193. /// <summary>
  194. /// 执行业务处理方法
  195. /// </summary>
  196. /// <param name="context"></param>
  197. /// <param name="validator"></param>
  198. bool ServiceProcess(HttpListenerContext context,HttpDataParser.Validator validator)
  199. {
  200. try
  201. {
  202. string key = validator.PlateCode + "." + validator.PlateColor + "." + validator.Channel + "." + validator.DataType;
  203. string result = HttpDataParser.GetRedisData(key);
  204. if (!string.IsNullOrEmpty(result) && result.Contains("@"))
  205. {
  206. SQ.Base.Log.WriteLog4("上级平台业务处理Get data from redis:result=" + result);
  207. string[] strs = result.Split('@');
  208. var type = strs[0];
  209. var json = strs[1];
  210. if ("real".Equals(type))
  211. {
  212. // 实时视频
  213. JTSDownRealVideoRequest jtSDownRealVideoRequest = json.ParseJSON<JTSDownRealVideoRequest>();
  214. GovernmentWebClientManage.AcceptRealConnect(context, key, validator.Sim, (byte)validator.Channel, (byte)validator.DataType);
  215. return true;
  216. }
  217. else if ("back".Equals(type))
  218. {
  219. // 回放视频
  220. JTRTDownPlayBackMsgStartUp jtRTDownPlayBackMsgStartUp = json.ParseJSON<JTRTDownPlayBackMsgStartUp>();
  221. GovernmentWebClientManage.AcceptBackConnect(context, key, validator.Sim, (byte)validator.Channel, jtRTDownPlayBackMsgStartUp.PLAYBACK_STARTTIME.UNIXtoDateTime(), (long)jtRTDownPlayBackMsgStartUp.PLAYBACK_ENDTIME, (AudioVideoFlag)validator.DataType);
  222. return true;
  223. }
  224. }
  225. else
  226. {
  227. SQ.Base.Log.WriteLog4("上级平台业务处理Get data from redis:result="+result);
  228. }
  229. }
  230. catch (Exception ex)
  231. {
  232. SQ.Base.ErrorLog.WriteLog4Ex("上级平台业务处理ServiceProcess read data from redis:", ex);
  233. }
  234. return false;
  235. }
  236. }
  237. }



相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载