WsSession.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.Extensions.Primitives;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Net.WebSockets;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace EVCB_OCPP.WSServer.Service.WsService
  11. {
  12. public class WsSession
  13. {
  14. public WsSession()
  15. {
  16. }
  17. public PathString? Path { get; set; }
  18. public string UriScheme { get; set; }
  19. public string AuthHeader { get; set; }
  20. public string SessionID { get; set; }
  21. public IPEndPoint Endpoint { get; internal set; }
  22. public StringValues Origin { get; internal set; }
  23. public DateTime LastActiveTime { get; set; }
  24. private WebSocket _WebSocket;
  25. public WebSocket ClientWebSocket
  26. {
  27. get => _WebSocket;
  28. set
  29. {
  30. Init(value);
  31. }
  32. }
  33. public WebSocketState State => ClientWebSocket.State;
  34. public string SecWebSocketProtocol => ClientWebSocket.SubProtocol;
  35. public SemaphoreSlim EndConnSemaphore { get; } = new SemaphoreSlim(0);
  36. //public event OCPPClientDataEventHandler<WsSession, String> m_ReceiveData;
  37. public event EventHandler<string> SessionClosed;
  38. private CancellationTokenSource disconnectCancellationTokenSource = new CancellationTokenSource();
  39. private Task ReceiveLoopTask;
  40. private void Init(WebSocket webSocket)
  41. {
  42. _WebSocket = webSocket;
  43. ReceiveLoopTask = StartReceivd(webSocket, disconnectCancellationTokenSource.Token);
  44. }
  45. private async Task StartReceivd(WebSocket webSocket, CancellationToken token)
  46. {
  47. string received = string.Empty;
  48. while (!token.IsCancellationRequested)
  49. {
  50. var buffer = new byte[1024 * 4];
  51. var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), token);
  52. if (result.CloseStatus.HasValue)
  53. {
  54. _ = InternalClose(result.CloseStatus.Value);
  55. break;
  56. }
  57. received += Encoding.UTF8.GetString(buffer, 0, result.Count);
  58. //m_ReceiveData?.Invoke(this, received);
  59. LastActiveTime = DateTime.UtcNow;
  60. if (result.EndOfMessage)
  61. {
  62. HandleReceivedData(received);
  63. received = string.Empty;
  64. }
  65. }
  66. }
  67. internal virtual void HandleReceivedData(string data)
  68. {
  69. }
  70. internal void Send(string dataString)
  71. {
  72. var data = Encoding.UTF8.GetBytes(dataString);
  73. ClientWebSocket.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: disconnectCancellationTokenSource.Token);
  74. }
  75. internal void Send(byte[] data, int offset, int length)
  76. {
  77. ClientWebSocket.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: disconnectCancellationTokenSource.Token);
  78. }
  79. internal Task Close()
  80. {
  81. return InternalClose(WebSocketCloseStatus.NormalClosure, "ServerShutdown");
  82. }
  83. private Task InternalClose(WebSocketCloseStatus closeStatus)
  84. {
  85. return InternalClose(closeStatus , null);
  86. }
  87. private async Task InternalClose(WebSocketCloseStatus closeStatus, string description)
  88. {
  89. try
  90. {
  91. await _WebSocket.CloseAsync(closeStatus, description, default);
  92. }
  93. finally
  94. {
  95. _WebSocket.Dispose();
  96. }
  97. disconnectCancellationTokenSource.Cancel();
  98. SessionClosed?.Invoke(this, closeStatus.ToString());
  99. EndConnSemaphore.Release();
  100. }
  101. }
  102. }