Hello all,
When my site is deployed and multiple people as using it I am trying to understand if my server were able to handle these requests from multiple people. At first itll only be 10-20 people but I plan on it growing. On the UI since its front end do the websockets open from from the client’s side and not on my server. Then on the API if it would be as many users that are logged in if they will each have their own websocket stream open to my server?
In addition, I was wondering this, if I had the exchange websocket open just 1 of them if it was on my server could I have every user just use that 1 stream and not need multiple of them?
I have never built a site using websockets before so I am not sure the right path to take. Am I thinking of this the right way or should both socket connections be opened on the client end and them it wouldn’t use much if not any of my server resources for that connection.
I am currently just using normal Websockets from javascript and c#.
Any input here would be greatly appreciated.
Thank you all.
What I have tried:
I been trying to grasp how this works and been doing research but still I do not have a full understanding. I have a trading bot that I am creating. It has an api that creates Trades on an exchange. I have a UI that shows everything. Currently I have 2 separate websocket connections. 1 for all the incoming trades from the exchange. This is on the UI. The 2nd is the users current trades as they update or change status, this one is currently on the API and it sends an httpclient to the UI as they occur which is a lot less frequently because it’s the users specific trades.
function updateState() {
if (!socket) {
} else {
switch (socket.readyState) {
case WebSocket.CLOSED:
stateLabel.innerHTML = "Closed";
connectionUrl.disabled = false;
connectButton.disabled = false;
break;
case WebSocket.CLOSING:
stateLabel.innerHTML = "Closing...";
break;
case WebSocket.CONNECTING:
stateLabel.innerHTML = "Connecting...";
break;
case WebSocket.OPEN:
stateLabel.innerHTML = "Open";
break;
default:
stateLabel.innerHTML = "Unknown WebSocket State: " + socket.readyState;
break;
}
}
}
connectButton.onclick = function () {
stateLabel.innerHTML = "Connecting...";
socket = new WebSocket(connectionUrl.value);
socket.onopen = function (event) {
$.ajax({
url: '@Url.Action("WebSocketsCacheOn", "Home")',
type: "GET",
dataType: "JSON",
}).done(function (e) {
@*$.ajax({
url: '@Url.Action("CaptureUserTradeData", "Home")',
type: "GET",
});*@
$('#connectButton').addClass('btn-success');
$('#connectButton').removeClass('btn-secondary');
})
stateLabel.innerHTML = "Connected";
}
socket.onclose = function (event) {
stateLabel.innerHTML = "Closing...";
stateLabel.innerHTML = "Closed.";
$('#connectButton').removeClass('btn-success');
$('#connectButton').addClass('btn-secondary');
};
socket.onerror = function (e) {
$("#divadd").innerHTML += "Errored";
};
socket.onmessage = function (event) {
var obj = JSON.parse(event.data.replace('\\', ''));
var trade = event.data.replace('\\', '');
$("#divadd").html += "<p>" + obj.p + "</p>";
updatePrice(obj);
addData(obj);
if (activeTrades) {
executeTradeAsync();
}
}
};
Startup.cs
app.UseWebSockets();
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(120),
};
app.UseWebSockets(webSocketOptions);
app.Use(async (context, next) =>
{
if (context.Request.Path == "/ws")
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
await Echo(context, webSocket);
}
else
{
context.Response.StatusCode = 400;
}
}
else
{
await next();
}
});
async Task Echo(HttpContext context, WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer),
CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType,
result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
Console.WriteLine(result);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription,
CancellationToken.None);
}