Hello I'm currently implementing a websocket component to my very basic site. I'm running .NET Core 3.1 HTTP Listener for serving html, I've been stumped by implementing websockets.
I've worked with TCP in C# before and understand the flow of everything but websockets are a new thing to me. Here is the C# code for accepting websockets
[Route("/socket", "GET")]
public static async Task upgrade(HttpListenerContext c)
{
if (!c.Request.IsWebSocketRequest)
{
c.Response.StatusCode = 400;
c.Response.Close();
return;
}
try
{
var sock = (await c.AcceptWebSocketAsync(null)).WebSocket;
byte[] buff = new byte[1024];
var r = await sock.ReceiveAsync(buff, System.Threading.CancellationToken.None);
}
catch (Exception x)
{
Console.WriteLine($"Got exception: {x}");
}
//WebSocketHandler.AddSocket(sock);
}
I've added var r = await sock.ReceiveAsync(buff, System.Threading.CancellationToken.None);
to this function because originally I was getting the exception in my WebSocketHandler class, so I moved the code to the one function to test.
Here is the client:
<script>
let socket = new WebSocket("ws://localhost:3000/socket");
socket.onopen = function (event) {
console.log("[ OPENED ] - Opened Websocket!");
};
socket.onclose = function (event) {
console.log("[ CLOSED ] - Socket closed");
};
socket.onerror = function (error) {
console.log("[ ERROR ] - Got websocket error:");
console.error(error);
};
socket.onmessage = function (event) {
// This function will be responsible for handling events
console.log("[ MESSAGE ] - Message received: ");
const content = JSON.parse(event.data);
console.log(content);
};
</script>
Here is the output in the console for the client:
Navigated to http://127.0.0.1:5500/index.html
index.html:556 [ OPENED ] - Opened Websocket!
index.html:569 [ CLOSED ] - Socket closed
And here is the exception from the C# server:
Got exception: System.Net.WebSockets.WebSocketException (997): The remote party closed the WebSocket connection without completing the close handshake.
at System.Net.WebSockets.WebSocketBase.WebSocketOperation.Process(Nullable`1 buffer, CancellationToken cancellationToken)
at System.Net.WebSockets.WebSocketBase.ReceiveAsyncCore(ArraySegment`1 buffer, CancellationToken cancellationToken)
at SwissbotCore.HTTP.Routes.UpgradeWebsocket.upgrade(HttpListenerContext c) in C:\Users\plynch\source\repos\SwissbotCore\SwissbotCore\HTTP\Routes\UpgradeWebsocket.cs:line 29
I can provide the http requests that the client sends if need be but I am completely stumped on this, any help will be greatly appreciated.
You might want to read up on The Close Handshake in Section 1.4 in RFC 6455 and also Close the WebSocket Connection in Section 7.1.1 in RFC 6455.
Essentially, you need to let the WebSocket endpoint know you are going to close the socket, before you terminate the socket.
For your server side, you should probably be catching this exception, as this can also happen in production scenarios when network issues occur.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With