如何在C#.NET Core 3.1中使用Web套接字? [英] How to use web sockets in C# .NET Core 3.1?

查看:82
本文介绍了如何在C#.NET Core 3.1中使用Web套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Web应用程序中实现实时通知.只有作为我的Web应用程序管理员的用户才能看到通知.
因此,我在我的startup.cs文件中设置了Web套接字,我认为这不是正确的方法

I am trying to implement live notifications in my web application. Only the users which are administrators in my web app should see the notifications.
So I setup the web socket in my startup.cs file which I think is not the right way

Startup.cs

Startup.cs

var webSocketOptions = new WebSocketOptions()
{
    KeepAliveInterval = TimeSpan.FromSeconds(120),
    ReceiveBufferSize = 4 * 1024
};
app.UseWebSockets(webSocketOptions);
app.Use(async (context, next) =>
    {
         if (context.Request.Path == "/ws")
         {
             if (context.WebSockets.IsWebSocketRequest)
             {
                  WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                        
             }
             else
             {
                 context.Response.StatusCode = 400;
             }
         }
         else
         {
            await next();
         }
   });

这是我的Javascript

and this is my Javascript

window.onload = () => {
    if (/*User is Admin*/) {

        //Establish Websocket
        var socket = new WebSocket("wss:localhost:44301/ws");

        console.log(socket.readyState);

        socket.onerror = function (error) {
            console.log('WebSocket Error: ' + error);
        };

        socket.onopen = function (event) {          
            console.log("Socket connection opened")
        };

        // Handle messages sent by the server.
        socket.onmessage = function (event) {
            var data = event.data;
            console.log(data);
            //Draw some beautiful HTML notification
        };
    }
}

现在一切正常,但是我不知道如何从服务器控制器发送消息,诸如此类

now this all works, but I don't know how to send messages from my server controllers, something like this

[HttpGet]
public async Task<IActionResult> Foo(WebSocket webSocket)
{
    //What I am trying to do is send message from the open web socket connection.
    var buffer = new byte[1024 * 4];
    buffer = Encoding.UTF8.GetBytes("Foo");

    await webSocket.SendAsync(new ArraySegment<byte>(buffer),WebSocketMessageType.Text,true,CancellationToken.None);
    return View()
}

我不知道该如何处理.我想做的是,如果用户是管理员,请打开Web套接字并从其他用户的操作中发送一些数据(这意味着从我的某些控制器从该打开的Web套接字写入消息)

I don't know how to approach this. What I wanna do is if the user is admin, open web socket and send some data from the other users actions, (which means writing messages from that opened web socket from some of my controllers)

推荐答案

要能够从控制器发送到已连接的Web套接字,您必须能够访问这些连接,作为持有这些连接的对象.

To be able to send from a controller to the connected web sockets you'd have to be able to access these connections, as an object that holds these connections.

此答案显示了如何处理具有单独类的单个连接以及如何使连接保持活动状态(等待客户端.RunAsync();).

This answer shows how to handle a single connection with a separate class and to keep the connection alive (await client.RunAsync();).

在这种情况下,您可能需要创建另一个类ConnectionContainer.它可能只有一个ConcurrentDictionary来保存所有传入的连接.然后,您必须使该类可用于控制器.可以通过依赖注入来完成.在Startup.cs中:

After doing this, in your case, you'd probably create another class, ConnectionContainer. It could have just a ConcurrentDictionary to hold all incoming connections. Then you'd have to make this class available to a controller. It can be done with dependency injection. In Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(new ConnectionContainer());
    ...

}

然后在控制器的ctor中添加ConnectionContainer作为参数并将其保存为私有字段:

And in the controller's ctor add ConnectionContainer as a parameter and save it as a private field:

 public class BroadcastController
 {
     private readonly ConnectionContainer _connectionContainer;

     public BroadcastController(ConnectionContainer connectionContainer)
     {
         _connectionContainer = connectionContainer;
     }
 }

您的Foo方法可以直接使用连接,也可以在ConnectionContainer中实现广播方法(您可以对其进行复用,并且可以很好地封装).

Your Foo method could either use the connections directly, or you could implement a broadcast method in ConnectionContainer (you may have reuse for that, and it'd be nicely encapsulated).

顺便说一句,如果您想将websockets用于带有asp.net核心的json/文本消息,我同意其他答案-signalR将更易于使用(代码更少).如果您想完全控制websocket并对其进行完全优化,那么您的代码会更好,因为您可以将二进制数据直接传输到Web客户端(signalR不支持).可以在客户端中使用 DataView使用二进制数据.

Btw, if you'd like to use websockets for json/text messages with asp.net core, I agree with the other answers - signalR will be easier to use (less code). If you'd like full control over the websocket and to have it fully optimized to your needs, your code would be better, as you could transfer binary data directly to the web client (which isn't supported by signalR). The binary data can be used in the client with a DataView.

这篇关于如何在C#.NET Core 3.1中使用Web套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆