To build a WebSocket server using SuperSocket in an ASP.NET Core Web API project, install the SuperSocket.WebSocket.Server NuGet package (referred to here as SuperWebSocket). This guide demonstrates how to embed and manage a WebSocket server within a .NET 5+ Web API application using version 2.0.0-beta.10 of the library.
The approach assumes familiarity with both ASP.NET Core Web API and SuperSocket concepts.
- Implement a Custom WebSocket Service
Create a service that configures and hosts the WebSocket server. Instead of relying on external configuration files, this implemantation uses in-memory configuration to dynamically set the listening port via the application’s IConfiguration. The service also ensures proper cleanup by disposing the host when the application shuts down.
public interface IWebSocketHostService
{
Task StartAsync();
Task StopAsync();
}
public class WebSocketHostService : IWebSocketHostService
{
private IHost? _host;
private readonly ILogger<WebSocketHostService> _logger;
private readonly int _listeningPort;
public WebSocketHostService(ILogger<WebSocketHostService> logger, IConfiguration config)
{
_logger = logger;
var portStr = config["WebSocket:Port"];
_listeningPort = int.TryParse(portStr, out var p) ? p : 6666;
if (portStr == null)
{
_logger.LogWarning("WebSocket port not configured. Using default port {Port}.", _listeningPort);
}
}
public async Task StartAsync()
{
try
{
_host = WebSocketHostBuilder.Create()
.UseWebSocketMessageHandler(async (session, message) =>
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
Console.WriteLine($"{timestamp} Received: {message.Message}");
var response = $"{timestamp} Echo from server: {message.Message}";
await session.SendAsync(response);
})
.ConfigureAppConfiguration((_, builder) =>
{
builder.AddInMemoryCollection(new Dictionary<string, string>
{
["serverOptions:name"] = "ApiWebSocketServer",
["serverOptions:listeners:0:ip"] = "Any",
["serverOptions:listeners:0:port"] = _listeningPort.ToString()
});
})
.ConfigureLogging((_, logging) =>
{
logging.AddConsole();
})
.Build();
await _host.RunAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to start WebSocket server.");
}
}
public async Task StopAsync()
{
if (_host == null) return;
try
{
await _host.StopAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error during WebSocket server shutdown.");
}
finally
{
_host.Dispose();
_host = null;
}
}
}
- Register the Service
In Startup.cs, register the service as a singleton in the DI container:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSingleton<IWebSocketHostService, WebSocketHostService>();
}
- Launch the WebSocket Server
Start the WebSocket server after the Web API pipeline is configured. Use an asnychronous background task to avoid blocking the main startup flow:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Start WebSocket server in background
var webSocketService = app.ApplicationServices.GetRequiredService<IWebSocketHostService>();
_ = Task.Run(() => webSocketService.StartAsync());
}
Note: Starting long-running services like this in Configure is acceptable for simple scenarios. For production-grade applications, consider implementing IHostedService instead to integrate cleanly with the host lifecycle.