diff --git a/source/NetCoreServer/IWebSocket.cs b/source/NetCoreServer/IWebSocket.cs
index 0ea91e8..63f6181 100644
--- a/source/NetCoreServer/IWebSocket.cs
+++ b/source/NetCoreServer/IWebSocket.cs
@@ -53,7 +53,8 @@ void OnWsReceived(byte[] buffer, long offset, long size) {}
/// Received buffer
/// Received buffer offset
/// Received buffer size
- void OnWsClose(byte[] buffer, long offset, long size) {}
+ /// WebSocket close status (default is 1000)
+ void OnWsClose(byte[] buffer, long offset, long size, int status = 1000) {}
///
/// Handle WebSocket ping notification
diff --git a/source/NetCoreServer/NetCoreServer.csproj b/source/NetCoreServer/NetCoreServer.csproj
index bd978d8..27df22b 100644
--- a/source/NetCoreServer/NetCoreServer.csproj
+++ b/source/NetCoreServer/NetCoreServer.csproj
@@ -2,7 +2,7 @@
net6.0
- 6.6.0.0
+ 6.7.0.0
Ivan Shynkarenka
Copyright (c) 2019-2022 Ivan Shynkarenka
https://github.com/chronoxor/NetCoreServer
diff --git a/source/NetCoreServer/UdpClient.cs b/source/NetCoreServer/UdpClient.cs
index 76f8365..e982277 100644
--- a/source/NetCoreServer/UdpClient.cs
+++ b/source/NetCoreServer/UdpClient.cs
@@ -457,7 +457,7 @@ public virtual long Send(EndPoint endpoint, ReadOnlySpan buffer)
try
{
// Sent datagram to the server
- int sent = Socket.SendTo(buffer, SocketFlags.None, endpoint);
+ long sent = Socket.SendTo(buffer, SocketFlags.None, endpoint);
if (sent > 0)
{
// Update statistic
@@ -632,7 +632,7 @@ public virtual long Receive(ref EndPoint endpoint, byte[] buffer, long offset, l
try
{
// Receive datagram from the server
- int received = Socket.ReceiveFrom(buffer, (int)offset, (int)size, SocketFlags.None, ref endpoint);
+ long received = Socket.ReceiveFrom(buffer, (int)offset, (int)size, SocketFlags.None, ref endpoint);
// Update statistic
DatagramsReceived++;
diff --git a/source/NetCoreServer/UdpServer.cs b/source/NetCoreServer/UdpServer.cs
index 250ed5b..13cd1eb 100644
--- a/source/NetCoreServer/UdpServer.cs
+++ b/source/NetCoreServer/UdpServer.cs
@@ -473,7 +473,7 @@ public virtual long Send(EndPoint endpoint, ReadOnlySpan buffer)
try
{
// Sent datagram to the client
- int sent = Socket.SendTo(buffer, SocketFlags.None, endpoint);
+ long sent = Socket.SendTo(buffer, SocketFlags.None, endpoint);
if (sent > 0)
{
// Update statistic
@@ -610,7 +610,7 @@ public virtual long Receive(ref EndPoint endpoint, byte[] buffer, long offset, l
try
{
// Receive datagram from the client
- int received = Socket.ReceiveFrom(buffer, (int)offset, (int)size, SocketFlags.None, ref endpoint);
+ long received = Socket.ReceiveFrom(buffer, (int)offset, (int)size, SocketFlags.None, ref endpoint);
// Update statistic
DatagramsReceived++;
diff --git a/source/NetCoreServer/WebSocket.cs b/source/NetCoreServer/WebSocket.cs
index 75d2d73..e33f43e 100644
--- a/source/NetCoreServer/WebSocket.cs
+++ b/source/NetCoreServer/WebSocket.cs
@@ -253,7 +253,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)
{
- int size = buffer.Length;
+ long size = (((opcode & WS_CLOSE) == WS_CLOSE) && (buffer.Length > 0)) ? (buffer.Length + 2) : buffer.Length;
// Clear the previous WebSocket send buffer
WsSendBuffer.Clear();
@@ -263,7 +263,7 @@ public void PrepareSendFrame(byte opcode, bool mask, ReadOnlySpan buffer,
// Append WebSocket frame size
if (size <= 125)
- WsSendBuffer.Append((byte)((size & 0xFF) | (mask ? 0x80 : 0)));
+ WsSendBuffer.Append((byte)(((int)size & 0xFF) | (mask ? 0x80 : 0)));
else if (size <= 65535)
{
WsSendBuffer.Append((byte)(126 | (mask ? 0x80 : 0)));
@@ -284,11 +284,21 @@ public void PrepareSendFrame(byte opcode, bool mask, ReadOnlySpan buffer,
}
// Resize WebSocket frame buffer
- int offset = (int)WsSendBuffer.Size;
+ long offset = WsSendBuffer.Size;
WsSendBuffer.Resize(WsSendBuffer.Size + size);
+ int index = 0;
+
+ // Append WebSocket close status
+ if (((opcode & WS_CLOSE) == WS_CLOSE) && (buffer.Length > 0))
+ {
+ index += 2;
+ WsSendBuffer.Append((byte)((status >> 8) & 0xFF));
+ WsSendBuffer.Append((byte)(status & 0xFF));
+ }
+
// Mask WebSocket frame content
- for (int i = 0; i < size; i++)
+ for (int i = index; i < size; i++)
WsSendBuffer.Data[offset + i] = (byte)(buffer[i] ^ WsSendMask[i % 4]);
}
@@ -302,7 +312,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
{
lock (WsReceiveLock)
{
- var index = 0;
+ int index = 0;
// Clear received data after WebSocket frame was processed
if (WsFrameReceived)
@@ -339,7 +349,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
// Prepare WebSocket frame opcode and mask flag
if (WsReceiveFrameBuffer.Size < 2)
{
- for (int i = 0; i < 2; i++, index++, size--)
+ for (long i = 0; i < 2; i++, index++, size--)
{
if (size == 0)
return;
@@ -350,7 +360,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
byte opcode = (byte)(WsReceiveFrameBuffer[0] & 0x0F);
bool fin = ((WsReceiveFrameBuffer[0] >> 7) & 0x01) != 0;
bool mask = ((WsReceiveFrameBuffer[1] >> 7) & 0x01) != 0;
- int payload = WsReceiveFrameBuffer[1] & (~0x80);
+ long payload = WsReceiveFrameBuffer[1] & (~0x80);
// Prepare WebSocket opcode
WsOpcode = (opcode != 0) ? opcode : WsOpcode;
@@ -365,7 +375,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
{
if (WsReceiveFrameBuffer.Size < 4)
{
- for (int i = 0; i < 2; i++, index++, size--)
+ for (long i = 0; i < 2; i++, index++, size--)
{
if (size == 0)
return;
@@ -381,7 +391,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
{
if (WsReceiveFrameBuffer.Size < 10)
{
- for (int i = 0; i < 8; i++, index++, size--)
+ for (long i = 0; i < 8; i++, index++, size--)
{
if (size == 0)
return;
@@ -399,7 +409,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
{
if (WsReceiveFrameBuffer.Size < WsHeaderSize)
{
- for (int i = 0; i < 4; i++, index++, size--)
+ for (long i = 0; i < 4; i++, index++, size--)
{
if (size == 0)
return;
@@ -409,12 +419,12 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
}
}
- int total = WsHeaderSize + WsPayloadSize;
- int length = Math.Min(total - (int)WsReceiveFrameBuffer.Size, (int)size);
+ long total = WsHeaderSize + WsPayloadSize;
+ long length = Math.Min(total - WsReceiveFrameBuffer.Size, size);
// Prepare WebSocket frame payload
- WsReceiveFrameBuffer.Append(buffer[((int)offset + index)..((int)offset + index + length)]);
- index += length;
+ WsReceiveFrameBuffer.Append(buffer[((int)offset + index)..((int)offset + index + (int)length)]);
+ index += (int)length;
size -= length;
// Process WebSocket frame
@@ -423,11 +433,11 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
// Unmask WebSocket frame content
if (mask)
{
- for (int i = 0; i < WsPayloadSize; i++)
+ for (long i = 0; i < WsPayloadSize; i++)
WsReceiveFinalBuffer.Append((byte)(WsReceiveFrameBuffer[WsHeaderSize + i] ^ WsReceiveMask[i % 4]));
}
else
- WsReceiveFinalBuffer.Append(WsReceiveFrameBuffer.AsSpan().Slice(WsHeaderSize, WsPayloadSize));
+ WsReceiveFinalBuffer.Append(WsReceiveFrameBuffer.AsSpan().Slice((int)WsHeaderSize, (int)WsPayloadSize));
WsFrameReceived = true;
@@ -452,8 +462,18 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
}
case WS_CLOSE:
{
+ int sindex = 0;
+ int status = 1000;
+
+ // Read WebSocket close status
+ if (WsReceiveFinalBuffer.Size > 2)
+ {
+ sindex += 2;
+ status = ((WsReceiveFinalBuffer[0] << 8) | (WsReceiveFinalBuffer[1] << 0));
+ }
+
// Call the WebSocket close handler
- _wsHandler.OnWsClose(WsReceiveFinalBuffer.Data, 0, WsReceiveFinalBuffer.Size);
+ _wsHandler.OnWsClose(WsReceiveFinalBuffer.Data, sindex, WsReceiveFinalBuffer.Size - sindex, status);
break;
}
case WS_BINARY:
@@ -473,7 +493,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
///
/// Required WebSocket receive frame size
///
- public int RequiredReceiveFrameSize()
+ public long RequiredReceiveFrameSize()
{
lock (WsReceiveLock)
{
@@ -482,23 +502,23 @@ public int RequiredReceiveFrameSize()
// Required WebSocket frame opcode and mask flag
if (WsReceiveFrameBuffer.Size < 2)
- return 2 - (int)WsReceiveFrameBuffer.Size;
+ return 2 - WsReceiveFrameBuffer.Size;
bool mask = ((WsReceiveFrameBuffer[1] >> 7) & 0x01) != 0;
- int payload = WsReceiveFrameBuffer[1] & (~0x80);
+ long payload = WsReceiveFrameBuffer[1] & (~0x80);
// Required WebSocket frame size
if ((payload == 126) && (WsReceiveFrameBuffer.Size < 4))
- return 4 - (int)WsReceiveFrameBuffer.Size;
+ return 4 - WsReceiveFrameBuffer.Size;
if ((payload == 127) && (WsReceiveFrameBuffer.Size < 10))
- return 10 - (int)WsReceiveFrameBuffer.Size;
+ return 10 - WsReceiveFrameBuffer.Size;
// Required WebSocket frame mask
if ((mask) && (WsReceiveFrameBuffer.Size < WsHeaderSize))
- return WsHeaderSize - (int)WsReceiveFrameBuffer.Size;
+ return WsHeaderSize - WsReceiveFrameBuffer.Size;
// Required WebSocket frame payload
- return WsHeaderSize + WsPayloadSize - (int)WsReceiveFrameBuffer.Size;
+ return WsHeaderSize + WsPayloadSize - WsReceiveFrameBuffer.Size;
}
}
@@ -561,15 +581,15 @@ public void ClearWsBuffers()
///
/// Received frame opcode
///
- internal int WsOpcode;
+ internal byte WsOpcode;
///
/// Received frame header size
///
- internal int WsHeaderSize;
+ internal long WsHeaderSize;
///
/// Received frame payload size
///
- internal int WsPayloadSize;
+ internal long WsPayloadSize;
///
/// Receive buffer lock
diff --git a/source/NetCoreServer/WsClient.cs b/source/NetCoreServer/WsClient.cs
index 46fa9e7..ce7bbb7 100644
--- a/source/NetCoreServer/WsClient.cs
+++ b/source/NetCoreServer/WsClient.cs
@@ -220,9 +220,9 @@ public string ReceiveText()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = base.Receive(cache.Data, 0, required);
if (received != required)
return result.ExtractString(0, result.Data.Length);
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -251,9 +251,9 @@ public Buffer ReceiveBinary()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = base.Receive(cache.Data, 0, required);
if (received != required)
return result;
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -378,7 +378,7 @@ public virtual void OnWsConnected(HttpRequest request) {}
public virtual void OnWsDisconnecting() {}
public virtual void OnWsDisconnected() {}
public virtual void OnWsReceived(byte[] buffer, long offset, long size) {}
- public virtual void OnWsClose(byte[] buffer, long offset, long size) { CloseAsync(1000); }
+ public virtual void OnWsClose(byte[] buffer, long offset, long size, int status = 1000) { CloseAsync(status); }
public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); }
public virtual void OnWsPong(byte[] buffer, long offset, long size) {}
public virtual void OnWsError(string error) { OnError(SocketError.SocketError); }
diff --git a/source/NetCoreServer/WsSession.cs b/source/NetCoreServer/WsSession.cs
index 2296244..a81f4ab 100644
--- a/source/NetCoreServer/WsSession.cs
+++ b/source/NetCoreServer/WsSession.cs
@@ -187,9 +187,9 @@ public string ReceiveText()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = base.Receive(cache.Data, 0, required);
if (received != required)
return result.ExtractString(0, result.Data.Length);
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -218,9 +218,9 @@ public Buffer ReceiveBinary()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = base.Receive(cache.Data, 0, required);
if (received != required)
return result;
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -330,7 +330,7 @@ public virtual void OnWsConnected(HttpRequest request) {}
public virtual void OnWsDisconnecting() {}
public virtual void OnWsDisconnected() {}
public virtual void OnWsReceived(byte[] buffer, long offset, long size) {}
- public virtual void OnWsClose(byte[] buffer, long offset, long size) { Close(1000); }
+ public virtual void OnWsClose(byte[] buffer, long offset, long size, int status = 1000) { Close(status); }
public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); }
public virtual void OnWsPong(byte[] buffer, long offset, long size) {}
public virtual void OnWsError(string error) { OnError(SocketError.SocketError); }
diff --git a/source/NetCoreServer/WssClient.cs b/source/NetCoreServer/WssClient.cs
index bc4906b..263b412 100644
--- a/source/NetCoreServer/WssClient.cs
+++ b/source/NetCoreServer/WssClient.cs
@@ -224,9 +224,9 @@ public string ReceiveText()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = (int)base.Receive(cache.Data, 0, required);
if (received != required)
return result.ExtractString(0, result.Data.Length);
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -255,9 +255,9 @@ public Buffer ReceiveBinary()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = (int)base.Receive(cache.Data, 0, required);
if (received != required)
return result;
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -382,7 +382,7 @@ public virtual void OnWsConnected(HttpRequest request) {}
public virtual void OnWsDisconnecting() {}
public virtual void OnWsDisconnected() {}
public virtual void OnWsReceived(byte[] buffer, long offset, long size) {}
- public virtual void OnWsClose(byte[] buffer, long offset, long size) { CloseAsync(1000); }
+ public virtual void OnWsClose(byte[] buffer, long offset, long size, int status = 1000) { CloseAsync(status); }
public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); }
public virtual void OnWsPong(byte[] buffer, long offset, long size) {}
public virtual void OnWsError(string error) { OnError(SocketError.SocketError); }
diff --git a/source/NetCoreServer/WssSession.cs b/source/NetCoreServer/WssSession.cs
index c0fb4da..7553d0b 100644
--- a/source/NetCoreServer/WssSession.cs
+++ b/source/NetCoreServer/WssSession.cs
@@ -187,9 +187,9 @@ public string ReceiveText()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = base.Receive(cache.Data, 0, required);
if (received != required)
return result.ExtractString(0, result.Data.Length);
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -218,9 +218,9 @@ public Buffer ReceiveBinary()
{
while (!WebSocket.WsFrameReceived)
{
- int required = WebSocket.RequiredReceiveFrameSize();
+ long required = WebSocket.RequiredReceiveFrameSize();
cache.Resize(required);
- int received = (int)base.Receive(cache.Data, 0, required);
+ long received = base.Receive(cache.Data, 0, required);
if (received != required)
return result;
WebSocket.PrepareReceiveFrame(cache.Data, 0, received);
@@ -330,7 +330,7 @@ public virtual void OnWsConnected(HttpRequest request) {}
public virtual void OnWsDisconnecting() {}
public virtual void OnWsDisconnected() {}
public virtual void OnWsReceived(byte[] buffer, long offset, long size) {}
- public virtual void OnWsClose(byte[] buffer, long offset, long size) { Close(1000); }
+ public virtual void OnWsClose(byte[] buffer, long offset, long size, int status = 1000) { Close(status); }
public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); }
public virtual void OnWsPong(byte[] buffer, long offset, long size) {}
public virtual void OnWsError(string error) { OnError(SocketError.SocketError); }