diff --git a/source/NetCoreServer/Buffer.cs b/source/NetCoreServer/Buffer.cs index 6d813e4..6beaf66 100644 --- a/source/NetCoreServer/Buffer.cs +++ b/source/NetCoreServer/Buffer.cs @@ -70,7 +70,9 @@ public override string ToString() return ExtractString(0, _size); } - // Clear the current buffer and its offset + /// + /// Clear the current buffer and its offset + /// public void Clear() { _size = 0; @@ -127,7 +129,9 @@ public void Reserve(long capacity) } } - // Resize the current buffer + /// + /// Resize the current buffer + /// public void Resize(long size) { Reserve(size); @@ -136,9 +140,13 @@ public void Resize(long size) _offset = _size; } - // Shift the current buffer offset + /// + /// Shift the current buffer offset + /// public void Shift(long offset) { _offset += offset; } - // Unshift the current buffer offset + /// + /// Unshift the current buffer offset + /// public void Unshift(long offset) { _offset -= offset; } #endregion diff --git a/source/NetCoreServer/IWebSocket.cs b/source/NetCoreServer/IWebSocket.cs index 63f6181..43d0919 100644 --- a/source/NetCoreServer/IWebSocket.cs +++ b/source/NetCoreServer/IWebSocket.cs @@ -2,6 +2,9 @@ namespace NetCoreServer { + /// + /// WebSocket interface + /// public interface IWebSocket { /// diff --git a/source/NetCoreServer/NetCoreServer.csproj b/source/NetCoreServer/NetCoreServer.csproj index ecaf544..229bdd4 100644 --- a/source/NetCoreServer/NetCoreServer.csproj +++ b/source/NetCoreServer/NetCoreServer.csproj @@ -2,7 +2,7 @@ net8.0 - 8.0.0.0 + 8.0.1.0 Ivan Shynkarenka Copyright (c) 2019-2023 Ivan Shynkarenka https://github.com/chronoxor/NetCoreServer @@ -15,6 +15,8 @@ true snupkg + True + 1591 diff --git a/source/NetCoreServer/SslServer.cs b/source/NetCoreServer/SslServer.cs index 737c904..06d9d3e 100644 --- a/source/NetCoreServer/SslServer.cs +++ b/source/NetCoreServer/SslServer.cs @@ -386,7 +386,9 @@ private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) #region Session management - // Server sessions + /// + /// Server sessions + /// protected readonly ConcurrentDictionary Sessions = new ConcurrentDictionary(); /// diff --git a/source/NetCoreServer/TcpServer.cs b/source/NetCoreServer/TcpServer.cs index 6ae13b1..645f382 100644 --- a/source/NetCoreServer/TcpServer.cs +++ b/source/NetCoreServer/TcpServer.cs @@ -376,7 +376,9 @@ private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) #region Session management - // Server sessions + /// + /// Server sessions + /// protected readonly ConcurrentDictionary Sessions = new ConcurrentDictionary(); /// diff --git a/source/NetCoreServer/UdsServer.cs b/source/NetCoreServer/UdsServer.cs index a4b271f..3d7fa96 100644 --- a/source/NetCoreServer/UdsServer.cs +++ b/source/NetCoreServer/UdsServer.cs @@ -282,7 +282,9 @@ private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) #region Session management - // Server sessions + /// + /// Server sessions + /// protected readonly ConcurrentDictionary Sessions = new ConcurrentDictionary(); /// diff --git a/source/NetCoreServer/WebSocket.cs b/source/NetCoreServer/WebSocket.cs index c032919..fb9f6a2 100644 --- a/source/NetCoreServer/WebSocket.cs +++ b/source/NetCoreServer/WebSocket.cs @@ -13,6 +13,10 @@ public class WebSocket : IWebSocket { private readonly IWebSocket _wsHandler; + /// + /// Initialize a new WebSocket + /// + /// WebSocket handler public WebSocket(IWebSocket wsHandler) { _wsHandler = wsHandler; ClearWsBuffers(); InitWsNonce(); } /// @@ -253,7 +257,7 @@ public bool PerformServerUpgrade(HttpRequest request, HttpResponse response) /// WebSocket status (default is 0) public void PrepareSendFrame(byte opcode, bool mask, ReadOnlySpan buffer, int status = 0) { - bool storeWSCloseStatus = ((opcode & WS_CLOSE) == WS_CLOSE) && (buffer.Length > 0); + bool storeWSCloseStatus = (opcode & WS_CLOSE) == WS_CLOSE; long size = storeWSCloseStatus ? (buffer.Length + 2) : buffer.Length; // Clear the previous WebSocket send buffer @@ -297,13 +301,13 @@ public void PrepareSendFrame(byte opcode, bool mask, ReadOnlySpan buffer, if (storeWSCloseStatus) { index += 2; - WsSendBuffer.Append((byte)((status >> 8) & 0xFF)); - WsSendBuffer.Append((byte)(status & 0xFF)); + WsSendBuffer.Data[offset + 0] = (byte)(((status >> 8) & 0xFF) ^ WsSendMask[0]); + WsSendBuffer.Data[offset + 1] = (byte)((status & 0xFF) ^ WsSendMask[1]); } // Mask WebSocket frame content for (int i = index; i < size; i++) - WsSendBuffer.Data[offset + i] = (byte)(buffer[i] ^ WsSendMask[i % 4]); + WsSendBuffer.Data[offset + i] = (byte)(buffer[i - index] ^ WsSendMask[i % 4]); } /// @@ -470,7 +474,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size) int status = 1000; // Read WebSocket close status - if (WsReceiveFinalBuffer.Size > 2) + if (WsReceiveFinalBuffer.Size >= 2) { sindex += 2; status = ((WsReceiveFinalBuffer[0] << 8) | (WsReceiveFinalBuffer[1] << 0)); diff --git a/source/NetCoreServer/WsClient.cs b/source/NetCoreServer/WsClient.cs index ce7bbb7..6d53fc6 100644 --- a/source/NetCoreServer/WsClient.cs +++ b/source/NetCoreServer/WsClient.cs @@ -45,8 +45,18 @@ public class WsClient : HttpClient, IWebSocket public override bool Connect() { _syncConnect = true; return base.Connect(); } public override bool ConnectAsync() { _syncConnect = false; return base.ConnectAsync(); } - public virtual bool Close(int status) { SendClose(status, Span.Empty); base.Disconnect(); return true; } - public virtual bool CloseAsync(int status) { SendCloseAsync(status, Span.Empty); base.DisconnectAsync(); return true; } + public virtual bool Close(int status) => Close(status, Span.Empty); + public virtual bool Close(int status, string text) => Close(status, Encoding.UTF8.GetBytes(text)); + public virtual bool Close(int status, ReadOnlySpan text) => Close(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool Close(int status, byte[] buffer) => Close(status, buffer.AsSpan()); + public virtual bool Close(int status, byte[] buffer, long offset, long size) => Close(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool Close(int status, ReadOnlySpan buffer) { SendClose(status, buffer); base.Disconnect(); return true; } + public virtual bool CloseAsync(int status) => CloseAsync(status, Span.Empty); + public virtual bool CloseAsync(int status, string text) => CloseAsync(status, Encoding.UTF8.GetBytes(text)); + public virtual bool CloseAsync(int status, ReadOnlySpan text) => CloseAsync(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool CloseAsync(int status, byte[] buffer) => CloseAsync(status, buffer.AsSpan()); + public virtual bool CloseAsync(int status, byte[] buffer, long offset, long size) => CloseAsync(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool CloseAsync(int status, ReadOnlySpan buffer) { SendClose(status, buffer); base.DisconnectAsync(); return true; } #endregion diff --git a/source/NetCoreServer/WsServer.cs b/source/NetCoreServer/WsServer.cs index e95a4d4..057f850 100644 --- a/source/NetCoreServer/WsServer.cs +++ b/source/NetCoreServer/WsServer.cs @@ -37,11 +37,16 @@ public class WsServer : HttpServer, IWebSocket #region Session management - public virtual bool CloseAll(int status) + public virtual bool CloseAll(int status) => CloseAll(status, Span.Empty); + public virtual bool CloseAll(int status, string text) => CloseAll(status, Encoding.UTF8.GetBytes(text)); + public virtual bool CloseAll(int status, ReadOnlySpan text) => CloseAll(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool CloseAll(int status, byte[] buffer) => CloseAll(status, buffer.AsSpan()); + public virtual bool CloseAll(int status, byte[] buffer, long offset, long size) => CloseAll(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool CloseAll(int status, ReadOnlySpan buffer) { lock (WebSocket.WsSendLock) { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, Span.Empty, status); + WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, status); if (!Multicast(WebSocket.WsSendBuffer.AsSpan())) return false; diff --git a/source/NetCoreServer/WsSession.cs b/source/NetCoreServer/WsSession.cs index a81f4ab..69a5b88 100644 --- a/source/NetCoreServer/WsSession.cs +++ b/source/NetCoreServer/WsSession.cs @@ -12,10 +12,19 @@ public class WsSession : HttpSession, IWebSocket { internal readonly WebSocket WebSocket; + /// + /// Initialize a new WebSocket session + /// + /// WebSocket server public WsSession(WsServer server) : base(server) { WebSocket = new WebSocket(this); } // WebSocket connection methods - public virtual bool Close(int status) { SendCloseAsync(status, Span.Empty); base.Disconnect(); return true; } + public virtual bool Close(int status) => Close(status, Span.Empty); + public virtual bool Close(int status, string text) => Close(status, Encoding.UTF8.GetBytes(text)); + public virtual bool Close(int status, ReadOnlySpan text) => Close(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool Close(int status, byte[] buffer) => Close(status, buffer.AsSpan()); + public virtual bool Close(int status, byte[] buffer, long offset, long size) => Close(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool Close(int status, ReadOnlySpan buffer) { SendCloseAsync(status, buffer); base.Disconnect(); return true; } #region WebSocket send text methods diff --git a/source/NetCoreServer/WssClient.cs b/source/NetCoreServer/WssClient.cs index 263b412..22cd009 100644 --- a/source/NetCoreServer/WssClient.cs +++ b/source/NetCoreServer/WssClient.cs @@ -49,8 +49,18 @@ public class WssClient : HttpsClient, IWebSocket public override bool Connect() { _syncConnect = true; return base.Connect(); } public override bool ConnectAsync() { _syncConnect = false; return base.ConnectAsync(); } - public virtual bool Close(int status) { SendClose(status, Span.Empty); base.Disconnect(); return true; } - public virtual bool CloseAsync(int status) { SendCloseAsync(status, Span.Empty); base.DisconnectAsync(); return true; } + public virtual bool Close(int status) => Close(status, Span.Empty); + public virtual bool Close(int status, string text) => Close(status, Encoding.UTF8.GetBytes(text)); + public virtual bool Close(int status, ReadOnlySpan text) => Close(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool Close(int status, byte[] buffer) => Close(status, buffer.AsSpan()); + public virtual bool Close(int status, byte[] buffer, long offset, long size) => Close(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool Close(int status, ReadOnlySpan buffer) { SendClose(status, buffer); base.Disconnect(); return true; } + public virtual bool CloseAsync(int status) => CloseAsync(status, Span.Empty); + public virtual bool CloseAsync(int status, string text) => CloseAsync(status, Encoding.UTF8.GetBytes(text)); + public virtual bool CloseAsync(int status, ReadOnlySpan text) => CloseAsync(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool CloseAsync(int status, byte[] buffer) => CloseAsync(status, buffer.AsSpan()); + public virtual bool CloseAsync(int status, byte[] buffer, long offset, long size) => CloseAsync(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool CloseAsync(int status, ReadOnlySpan buffer) { SendClose(status, buffer); base.DisconnectAsync(); return true; } #endregion diff --git a/source/NetCoreServer/WssServer.cs b/source/NetCoreServer/WssServer.cs index 630469e..823d422 100644 --- a/source/NetCoreServer/WssServer.cs +++ b/source/NetCoreServer/WssServer.cs @@ -41,11 +41,16 @@ public class WssServer : HttpsServer, IWebSocket #region Session management - public virtual bool CloseAll(int status) + public virtual bool CloseAll(int status) => CloseAll(status, Span.Empty); + public virtual bool CloseAll(int status, string text) => CloseAll(status, Encoding.UTF8.GetBytes(text)); + public virtual bool CloseAll(int status, ReadOnlySpan text) => CloseAll(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool CloseAll(int status, byte[] buffer) => CloseAll(status, buffer.AsSpan()); + public virtual bool CloseAll(int status, byte[] buffer, long offset, long size) => CloseAll(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool CloseAll(int status, ReadOnlySpan buffer) { lock (WebSocket.WsSendLock) { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, Span.Empty, status); + WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, status); if (!Multicast(WebSocket.WsSendBuffer.AsSpan())) return false; diff --git a/source/NetCoreServer/WssSession.cs b/source/NetCoreServer/WssSession.cs index 7553d0b..7424fb9 100644 --- a/source/NetCoreServer/WssSession.cs +++ b/source/NetCoreServer/WssSession.cs @@ -12,10 +12,19 @@ public class WssSession : HttpsSession, IWebSocket { internal readonly WebSocket WebSocket; + /// + /// Initialize a new WebSocket session + /// + /// WebSocket server public WssSession(WssServer server) : base(server) { WebSocket = new WebSocket(this); } // WebSocket connection methods - public virtual bool Close(int status) { SendCloseAsync(status, Span.Empty); base.Disconnect(); return true; } + public virtual bool Close(int status) => Close(status, Span.Empty); + public virtual bool Close(int status, string text) => Close(status, Encoding.UTF8.GetBytes(text)); + public virtual bool Close(int status, ReadOnlySpan text) => Close(status, Encoding.UTF8.GetBytes(text.ToArray())); + public virtual bool Close(int status, byte[] buffer) => Close(status, buffer.AsSpan()); + public virtual bool Close(int status, byte[] buffer, long offset, long size) => Close(status, buffer.AsSpan((int)offset, (int)size)); + public virtual bool Close(int status, ReadOnlySpan buffer) { SendCloseAsync(status, buffer); base.Disconnect(); return true; } #region WebSocket send text methods