WSCommandLinePlugin.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //------------------------------------------------------------------------------
  2. // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
  3. // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
  4. // CSDN博客:https://blog.csdn.net/qq_40374647
  5. // 哔哩哔哩视频:https://space.bilibili.com/94253567
  6. // Gitee源代码仓库:https://gitee.com/RRQM_Home
  7. // Github源代码仓库:https://github.com/RRQM
  8. // API首页:https://www.yuque.com/rrqm/touchsocket/index
  9. // 交流QQ群:234762506
  10. // 感谢您的下载和使用
  11. //------------------------------------------------------------------------------
  12. //------------------------------------------------------------------------------
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Reflection;
  17. using TouchSocket.Core;
  18. using TouchSocket.Sockets;
  19. namespace TouchSocket.Http.WebSockets
  20. {
  21. /// <summary>
  22. /// WS命令行插件。
  23. /// </summary>
  24. public abstract class WSCommandLinePlugin : WebSocketPluginBase
  25. {
  26. private readonly Dictionary<string, Method> pairs = new Dictionary<string, Method>();
  27. private readonly ILog m_logger;
  28. /// <summary>
  29. /// 字符串转换器,默认支持基础类型和Json。可以自定义。
  30. /// </summary>
  31. public StringConverter Converter { get; }
  32. /// <summary>
  33. /// 是否返回执行异常。
  34. /// </summary>
  35. public bool ReturnException { get; set; } = true;
  36. /// <summary>
  37. /// 当有执行异常时,不返回异常。
  38. /// </summary>
  39. /// <returns></returns>
  40. public WSCommandLinePlugin NoReturnException()
  41. {
  42. ReturnException = false;
  43. return this;
  44. }
  45. /// <summary>
  46. /// WSCommandLinePlugin
  47. /// </summary>
  48. /// <param name="logger"></param>
  49. /// <exception cref="ArgumentNullException"></exception>
  50. protected WSCommandLinePlugin(ILog logger)
  51. {
  52. m_logger = logger ?? throw new ArgumentNullException(nameof(logger));
  53. Converter = new StringConverter();
  54. var ms = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(a => a.Name.EndsWith("Command"));
  55. foreach (var item in ms)
  56. {
  57. pairs.Add(item.Name.Replace("Command", string.Empty), new Method(item));
  58. }
  59. }
  60. /// <summary>
  61. /// <inheritdoc/>
  62. /// </summary>
  63. /// <param name="client"></param>
  64. /// <param name="e"></param>
  65. protected override void OnHandleWSDataFrame(ITcpClientBase client, WSDataFrameEventArgs e)
  66. {
  67. if (e.DataFrame.Opcode == WSDataType.Text)
  68. {
  69. try
  70. {
  71. string[] strs = e.DataFrame.ToText().Split(' ');
  72. if (strs.Length > 0 && pairs.TryGetValue(strs[0], out Method method))
  73. {
  74. var ps = method.Info.GetParameters();
  75. object[] os = new object[ps.Length];
  76. int index = 0;
  77. for (int i = 0; i < ps.Length; i++)
  78. {
  79. if (ps[i].ParameterType.IsInterface && typeof(ITcpClientBase).IsAssignableFrom(ps[i].ParameterType))
  80. {
  81. os[i] = client;
  82. }
  83. else
  84. {
  85. os[i] = Converter.ConvertFrom(strs[index + 1], ps[i].ParameterType);
  86. index++;
  87. }
  88. }
  89. e.Handled = true;
  90. try
  91. {
  92. object result = method.Invoke(this, os);
  93. if (method.HasReturn)
  94. {
  95. if (client is HttpClient httpClient)
  96. {
  97. httpClient.SendWithWS(Converter.ConvertTo(result));
  98. }
  99. else if (client is HttpSocketClient httpSocketClient)
  100. {
  101. httpSocketClient.SendWithWS(Converter.ConvertTo(result));
  102. }
  103. }
  104. }
  105. catch (Exception ex)
  106. {
  107. if (ReturnException)
  108. {
  109. if (client is HttpClient httpClient)
  110. {
  111. httpClient.SendWithWS(Converter.ConvertTo(ex.Message));
  112. }
  113. else if (client is HttpSocketClient httpSocketClient)
  114. {
  115. httpSocketClient.SendWithWS(Converter.ConvertTo(ex.Message));
  116. }
  117. }
  118. }
  119. }
  120. }
  121. catch (Exception ex)
  122. {
  123. m_logger.Exception(this, ex);
  124. }
  125. }
  126. base.OnHandleWSDataFrame(client, e);
  127. }
  128. }
  129. }