WsSession.cs 3.4 KB

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