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