scratch-link/scratch-link-common/WebSocketListener.cs

69 lines
1.9 KiB
C#
Raw Permalink Normal View History

2022-04-11 15:38:02 -07:00
// <copyright file="WebSocketListener.cs" company="Scratch Foundation">
// Copyright (c) Scratch Foundation. All rights reserved.
// </copyright>
namespace ScratchLink;
2022-07-07 17:40:49 -07:00
using System;
using System.Threading;
2022-07-11 14:58:08 -07:00
using Fleck;
2022-04-11 15:38:02 -07:00
/// <summary>
/// Listen for WebSocket connections and direct them to service handlers.
/// </summary>
internal class WebSocketListener
{
private readonly CancellationTokenSource cts = new ();
2022-04-11 15:38:02 -07:00
2022-07-11 14:58:08 -07:00
private WebSocketServer server;
2022-04-11 15:38:02 -07:00
/// <summary>
2022-04-12 14:22:05 -07:00
/// Gets or sets the action which will be called when the listener receives a WebSocket connection.
2022-04-11 15:38:02 -07:00
/// </summary>
2022-07-11 14:58:08 -07:00
public Action<IWebSocketConnection> OnWebSocketConnection { get; set; }
2022-04-11 15:38:02 -07:00
/// <summary>
/// Start listening for connections. If already listening, stop and restart with the new prefix list.
/// </summary>
2022-07-11 14:58:08 -07:00
/// <param name="location">
/// The list of WS URL to listen on.
2022-04-11 15:38:02 -07:00
/// <example><code>
2022-07-11 14:58:08 -07:00
/// ws://0.0.0.0:1234/
/// ws://127.0.0.1/
2022-04-11 15:38:02 -07:00
/// </code></example>
/// </param>
2022-07-11 14:58:08 -07:00
public void Start(string location)
2022-04-11 15:38:02 -07:00
{
2022-07-11 14:58:08 -07:00
if (this.server != null)
2022-04-11 15:38:02 -07:00
{
2022-07-11 14:58:08 -07:00
this.server.ListenerSocket.Close();
this.server.Dispose();
2022-04-11 15:38:02 -07:00
}
2022-07-11 14:58:08 -07:00
this.server = new WebSocketServer(location);
this.server.ListenerSocket.NoDelay = true; // disable Nagle's algorithm
2022-04-11 15:38:02 -07:00
2022-07-11 14:58:08 -07:00
this.server.Start(socket =>
2022-04-11 15:38:02 -07:00
{
2022-07-11 14:58:08 -07:00
if (this.cts.IsCancellationRequested)
2022-04-11 15:38:02 -07:00
{
2022-07-11 14:58:08 -07:00
socket.Close(503); // Service Unavailable: the server is stopping
return;
2022-04-11 15:38:02 -07:00
}
2022-07-11 14:58:08 -07:00
this.OnWebSocketConnection(socket);
2022-04-11 15:38:02 -07:00
});
}
2022-04-12 14:22:05 -07:00
/// <summary>
/// Stop listening for connections and terminate processing of all ongoing requests.
/// </summary>
public void Stop()
2022-04-11 15:38:02 -07:00
{
2022-04-12 14:22:05 -07:00
this.cts.Cancel();
2022-07-11 14:58:08 -07:00
this.server.RestartAfterListenError = false; // work around statianzo/Fleck#325
this.server.ListenerSocket.Close();
this.server.Dispose();
2022-04-11 15:38:02 -07:00
}
}