WebsocketModule
The WebSocketModule installs a WebSocket endpoint on the server. It maps a single WebSocket route, upgrades the HTTP connection to WebSocket, then routes incoming messages by op.
Definition
/// <summary>
/// Use WebSocket Module
/// It setups a Middleware
/// </summary>
public static SimpleWServer UseWebSocketModule(this SimpleWServer server, Action<WebSocketOptions>? configure = null)The options are the following
/// <summary>
/// Single WS endpoint path (default "/ws")
/// </summary>
public string Prefix { get; set; } = "/ws";/// <summary>
/// Max message size after reassembly (default 1 MiB)
/// </summary>
public int MaxMessageBytes { get; set; } = 1 * 1024 * 1024;/// <summary>
/// If set, must be present in Sec-WebSocket-Protocol
/// </summary>
public string? RequiredSubProtocol { get; set; }/// <summary>
/// Optional authorization callback. Return Allowed to continue, Challenge to request authentication, or Forbidden to deny.
/// </summary>
public Func<HttpSession, AuthorizeResult>? Authorize { get; set; }/// <summary>
/// If set, periodically send ping to keep proxies/load balancers happy
/// </summary>
public TimeSpan? KeepAliveInterval { get; set; }/// <summary>
/// Global hub to allow broadcasts to rooms (and/or an "all" room)
/// </summary>
public WebSocketHub Hub { get; } = new();/// <summary>
/// Optional: automatically join every connection into this room
/// Handy to broadcast to everyone: options.Hub.BroadcastTextAsync("__all", ...)
/// Set to null to disable auto join
/// </summary>
public string? AutoJoinRoom { get; set; } = "__all";/// <summary>
/// Message router (exact match on msg.Op)
/// </summary>
public WebSocketRouter Router { get; } = new();/// <summary>
/// Called after successful handshake, before the router
/// (Typical: auth handshake, join rooms...)
/// </summary>
public Func<WebSocketConnection, WebSocketContext, ValueTask>? OnConnect { get; set; }/// <summary>
/// Called when the connection is closed (finally)
/// </summary>
public Func<WebSocketConnection, WebSocketContext, ValueTask>? OnDisconnect { get; set; }/// <summary>
/// Register a handler for an op
/// </summary>
/// <param name="op"></param>
/// <param name="handler"></param>
public void Map(string op, WebSocketMessageHandler handler);/// <summary>
/// Register fallback handler
/// </summary>
/// <param name="handler"></param>
public void OnUnknown(WebSocketMessageHandler handler);/// <summary>
/// Binary handler
/// </summary>
public void OnBinary(Func<WebSocketConnection, WebSocketContext, ReadOnlyMemory<byte>, ValueTask> handler)Authorization
Use WebSocketOptions.Authorize to reject a WebSocket connection before the handshake:
server.ConfigureChallenge(session => session.Response.Unauthorized().SendAsync());
server.UseWebSocketModule(options => {
options.Prefix = "/ws";
options.Authorize = session => session.Principal.IsAuthenticated
? AuthorizeResult.Allowed
: AuthorizeResult.Challenge;
});When Authorize returns AuthorizeResult.Challenge, the server-wide Challenge is invoked when configured and must send the response. Without it, the module responds with 403 Forbidden. Forbidden and unknown enum values always return 403 without invoking the challenge. Allowed continues processing; an absent callback also allows access. For any rejected decision, the HTTP session is not switched to WebSocket.
Envelope
Text handlers receive a WebSocketEnvelope.
/// <summary>
/// Envelope used for routing
/// </summary>
/// <param name="Op"></param>
/// <param name="Id"></param>
/// <param name="IsJson"></param>
/// <param name="RawUtf8"></param>
/// <param name="PayloadUtf8"></param>
public readonly record struct WebSocketEnvelope(
string Op,
string? Id,
bool IsJson,
ReadOnlyMemory<byte> RawUtf8,
ReadOnlyMemory<byte> PayloadUtf8
)/// <summary>
/// Try deserialize full payload into T.
/// Returns false if there is no payload or if deserialization fails.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <param name="options"></param>
/// <returns></returns>
public bool TryDeserializePayload<T>(out T? value, JsonSerializerOptions? options = null)Example
See examples of use.