C
C#2y ago
doom 🐘

❔ Websockets and Async

I am just trying to use websockets to send some events from server periodically. Once close is sent from the client, I need to stop it. But how do I process client message that only occurs once in a while.
using System.Net.WebSockets;
using System.Text;

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
var app = builder.Build();

app.UseWebSockets();

app.UseDefaultFiles();
app.UseStaticFiles();

app.Use(async (context, next) =>
{
if (context.Request.Path == "/ws")
{
if (context.WebSockets.IsWebSocketRequest)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
await Echo(context, webSocket);
}
else
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}
else
{
await next();
}
});

async Task Echo(HttpContext context, WebSocket webSocket)
{

var buffer = new byte[1024 * 4];
var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var message = Encoding.UTF8.GetBytes("Hello from server");

Task.Run(async () =>
{
receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
app.Logger.LogInformation("Received: " + receiveResult.CloseStatusDescription);
});

while (!receiveResult.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(message, 0, message.Length), WebSocketMessageType.Text, true, CancellationToken.None);
await Task.Delay(1000);

if (Encoding.UTF8.GetString(buffer).Contains("close"))
{
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, receiveResult.CloseStatusDescription, CancellationToken.None);
return;
}
}

app.Logger.LogInformation("Closing connection");
};

app.Run();
using System.Net.WebSockets;
using System.Text;

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
var app = builder.Build();

app.UseWebSockets();

app.UseDefaultFiles();
app.UseStaticFiles();

app.Use(async (context, next) =>
{
if (context.Request.Path == "/ws")
{
if (context.WebSockets.IsWebSocketRequest)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
await Echo(context, webSocket);
}
else
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}
else
{
await next();
}
});

async Task Echo(HttpContext context, WebSocket webSocket)
{

var buffer = new byte[1024 * 4];
var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var message = Encoding.UTF8.GetBytes("Hello from server");

Task.Run(async () =>
{
receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
app.Logger.LogInformation("Received: " + receiveResult.CloseStatusDescription);
});

while (!receiveResult.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(message, 0, message.Length), WebSocketMessageType.Text, true, CancellationToken.None);
await Task.Delay(1000);

if (Encoding.UTF8.GetString(buffer).Contains("close"))
{
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, receiveResult.CloseStatusDescription, CancellationToken.None);
return;
}
}

app.Logger.LogInformation("Closing connection");
};

app.Run();
3 Replies
Anton
Anton2y ago
do you mean, not close the connection by means of timeout?
doom 🐘
doom 🐘OP2y ago
i figured it out. assign task.run to a variable and use oncomplete method
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server