WssServer.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System;
  2. using System.Net;
  3. using System.Text;
  4. namespace NetCoreServer
  5. {
  6. /// <summary>
  7. /// WebSocket secure server
  8. /// </summary>
  9. /// <remarks> WebSocket secure server is used to communicate with clients using WebSocket protocol. Thread-safe.</remarks>
  10. public class WssServer : HttpsServer, IWebSocket
  11. {
  12. internal readonly WebSocket WebSocket;
  13. /// <summary>
  14. /// Initialize WebSocket server with a given IP address and port number
  15. /// </summary>
  16. /// <param name="context">SSL context</param>
  17. /// <param name="address">IP address</param>
  18. /// <param name="port">Port number</param>
  19. public WssServer(SslContext context, IPAddress address, int port) : base(context, address, port) { WebSocket = new WebSocket(this); }
  20. /// <summary>
  21. /// Initialize WebSocket server with a given IP address and port number
  22. /// </summary>
  23. /// <param name="context">SSL context</param>
  24. /// <param name="address">IP address</param>
  25. /// <param name="port">Port number</param>
  26. public WssServer(SslContext context, string address, int port) : base(context, address, port) { WebSocket = new WebSocket(this); }
  27. /// <summary>
  28. /// Initialize WebSocket server with a given DNS endpoint
  29. /// </summary>
  30. /// <param name="context">SSL context</param>
  31. /// <param name="endpoint">DNS endpoint</param>
  32. public WssServer(SslContext context, DnsEndPoint endpoint) : base(context, endpoint) { WebSocket = new WebSocket(this); }
  33. /// <summary>
  34. /// Initialize WebSocket server with a given IP endpoint
  35. /// </summary>
  36. /// <param name="context">SSL context</param>
  37. /// <param name="endpoint">IP endpoint</param>
  38. public WssServer(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { WebSocket = new WebSocket(this); }
  39. #region Session management
  40. public virtual bool CloseAll() => CloseAll(0, Span<byte>.Empty);
  41. public virtual bool CloseAll(int status) => CloseAll(status, Span<byte>.Empty);
  42. public virtual bool CloseAll(int status, string text) => CloseAll(status, Encoding.UTF8.GetBytes(text));
  43. public virtual bool CloseAll(int status, ReadOnlySpan<char> text) => CloseAll(status, Encoding.UTF8.GetBytes(text.ToArray()));
  44. public virtual bool CloseAll(int status, byte[] buffer) => CloseAll(status, buffer.AsSpan());
  45. public virtual bool CloseAll(int status, byte[] buffer, long offset, long size) => CloseAll(status, buffer.AsSpan((int)offset, (int)size));
  46. public virtual bool CloseAll(int status, ReadOnlySpan<byte> buffer)
  47. {
  48. lock (WebSocket.WsSendLock)
  49. {
  50. WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, status);
  51. if (!Multicast(WebSocket.WsSendBuffer.AsSpan()))
  52. return false;
  53. return base.DisconnectAll();
  54. }
  55. }
  56. #endregion
  57. #region Multicasting
  58. public override bool Multicast(ReadOnlySpan<byte> buffer)
  59. {
  60. if (!IsStarted)
  61. return false;
  62. if (buffer.IsEmpty)
  63. return true;
  64. // Multicast data to all WebSocket sessions
  65. foreach (var session in Sessions.Values)
  66. {
  67. if (session is WssSession wsSession)
  68. {
  69. if (wsSession.WebSocket.WsHandshaked)
  70. wsSession.SendAsync(buffer);
  71. }
  72. }
  73. return true;
  74. }
  75. #endregion
  76. #region WebSocket multicast text methods
  77. public bool MulticastText(string text) => MulticastText(Encoding.UTF8.GetBytes(text));
  78. public bool MulticastText(ReadOnlySpan<char> text) => MulticastText(Encoding.UTF8.GetBytes(text.ToArray()));
  79. public bool MulticastText(byte[] buffer) => MulticastText(buffer.AsSpan());
  80. public bool MulticastText(byte[] buffer, long offset, long size) => MulticastText(buffer.AsSpan((int)offset, (int)size));
  81. public bool MulticastText(ReadOnlySpan<byte> buffer)
  82. {
  83. lock (WebSocket.WsSendLock)
  84. {
  85. WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer);
  86. return Multicast(WebSocket.WsSendBuffer.AsSpan());
  87. }
  88. }
  89. #endregion
  90. #region WebSocket multicast binary methods
  91. public bool MulticastBinary(string text) => MulticastBinary(Encoding.UTF8.GetBytes(text));
  92. public bool MulticastBinary(ReadOnlySpan<char> text) => MulticastBinary(Encoding.UTF8.GetBytes(text.ToArray()));
  93. public bool MulticastBinary(byte[] buffer) => MulticastBinary(buffer.AsSpan());
  94. public bool MulticastBinary(byte[] buffer, long offset, long size) => MulticastBinary(buffer.AsSpan((int)offset, (int)size));
  95. public bool MulticastBinary(ReadOnlySpan<byte> buffer)
  96. {
  97. lock (WebSocket.WsSendLock)
  98. {
  99. WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer);
  100. return Multicast(WebSocket.WsSendBuffer.AsSpan());
  101. }
  102. }
  103. #endregion
  104. #region WebSocket multicast ping methods
  105. public bool MulticastPing(string text) => MulticastPing(Encoding.UTF8.GetBytes(text));
  106. public bool MulticastPing(ReadOnlySpan<char> text) => MulticastPing(Encoding.UTF8.GetBytes(text.ToArray()));
  107. public bool MulticastPing(byte[] buffer) => MulticastPing(buffer.AsSpan());
  108. public bool MulticastPing(byte[] buffer, long offset, long size) => MulticastPing(buffer.AsSpan((int)offset, (int)size));
  109. public bool MulticastPing(ReadOnlySpan<byte> buffer)
  110. {
  111. lock (WebSocket.WsSendLock)
  112. {
  113. WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer);
  114. return Multicast(WebSocket.WsSendBuffer.AsSpan());
  115. }
  116. }
  117. #endregion
  118. protected override SslSession CreateSession() { return new WssSession(this); }
  119. }
  120. }