C# 将websockets接口添加到独立进程

C# 将websockets接口添加到独立进程,c#,asp.net,multithreading,backgroundworker,asp.net-core,C#,Asp.net,Multithreading,Backgroundworker,Asp.net Core,如果我有一个连续运行的独立进程,是否有一个好的方法向该进程添加asp.net websocket接口,以便我可以发送消息与该进程交互,并广播状态更新?消息可能非常大和/或频繁 无需安排此进程,因为它将在应用程序启动后立即运行 我这样问是因为最初我以为我会运行一个asp.net应用程序,在启动时创建一个线程(我想是在startup.Configure?),但我一直在读到asp.net不是为拥有后台线程而设计的。使用Windows服务是我提出来的,但我是为Linux和OSX开发的 这就是我想要实现的

如果我有一个连续运行的独立进程,是否有一个好的方法向该进程添加asp.net websocket接口,以便我可以发送消息与该进程交互,并广播状态更新?消息可能非常大和/或频繁

无需安排此进程,因为它将在应用程序启动后立即运行


我这样问是因为最初我以为我会运行一个asp.net应用程序,在启动时创建一个线程(我想是在startup.Configure?),但我一直在读到asp.net不是为拥有后台线程而设计的。使用Windows服务是我提出来的,但我是为Linux和OSX开发的

这就是我想要实现的目标:

public class Startup
{
    BackgroundServer server;

    public void Configure(IApplicationBuilder app)
    {
        // start server in another thread
        Task task = new Task( () => server.run(); );
        task.Start();

        app.Map("/ws", webSocketsApp =>
        {
            //  need this to enable websocket middleware!
            webSocketsApp.UseWebSockets(new WebSocketOptions() {ReplaceFeature = true, });

            webSocketsApp.Use(async (context, next) =>
            {
                if (context.WebSockets.IsWebSocketRequest)
                {
                    var webSocket = await context.WebSockets.AcceptWebSocketAsync();
                    await Task.WhenAll([]{ProcessMessages(webSocket), ProcessSends(websocket)});
                    return;
                }
                await next();
            });
        });
    }

    private async Task ProcessMessages(WebSocket webSocket)
    {

        byte[] buffer = new byte[1024 * 4];
        var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        while (!result.CloseStatus.HasValue)
        {
            await server.sendMessage(websocket, message);
        }
        await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
    }

    private async Task ProcessSends(WebSocket webSocket)
    {
        while (!webSocket.isStateTerminal)
        {
            var message = await server.getMessage();
            await webSocket.SendAsync(new ArraySegment<byte>(message), Text, true, CancellationToken.None);
        }
        await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
    }

}
公共类启动
{
后台服务器;
公共void配置(IApplicationBuilder应用程序)
{
//在另一个线程中启动服务器
任务=新任务(()=>server.run(););
task.Start();
app.Map(“/ws”,webSocketsApp=>
{
//需要这个来启用websocket中间件!
UseWebSockets(新的WebSocketOptions(){ReplaceFeature=true,});
使用(异步(上下文,下一步)=>
{
if(context.WebSockets.IsWebSocketRequest)
{
var webSocket=await context.WebSockets.AcceptWebSocketAsync();
wait Task.WhenAll([]{ProcessMessages(webSocket),ProcessSends(webSocket)});
返回;
}
等待下一个();
});
});
}
专用异步任务处理消息(WebSocket WebSocket)
{
字节[]缓冲区=新字节[1024*4];
var result=await webSocket.ReceiveAsync(新的ArraySegment(缓冲区),CancellationToken.None);
而(!result.CloseStatus.HasValue)
{
wait server.sendMessage(websocket,message);
}
等待webSocket.CloseAsync(result.CloseStatus.Value、result.CloseStatusDescription、CancellationToken.None);
}
专用异步任务ProcessSends(WebSocket WebSocket)
{
而(!webSocket.isStateTerminal)
{
var message=wait server.getMessage();
等待webSocket.SendAsync(新的ArraySegment(消息),文本,true,CancellationToken.None);
}
等待webSocket.CloseAsync(result.CloseStatus.Value、result.CloseStatusDescription、CancellationToken.None);
}
}

为什么是WebSocket?另外,不是ASP.NET本身不是为后台线程设计的,而是托管环境中更常见的问题。因为您似乎有自己的托管环境(自定义可执行文件),所以这不适用。只有常见的多线程复杂性才相关:)您可能希望使用
Task.Factory.StartNew(()=>{…},TaskCreationOptions.longlunning)
而不是
new Task
。不过,我们使用WebSocket允许基于web的客户端与此进程交互。一个客户端可以发送一个信号,该信号一旦处理完毕,就需要向所有其他连接的客户端发送更新。感谢您提供的长时间运行任务提示!关于ASP.NET不是为后台线程设计的,我读过关于ASP.NET实例由于各种原因(低负载、网络配置更改)而被回收的报道,这些原因可能会中断后台线程。“使用Windows服务是被提出来的,但我是为Linux和OSX开发的。”对我来说,这听起来是正确的解决方案。那么,作为守护进程运行您的服务到底有什么问题?@Voo在dotnet中IPC是什么样子的。net似乎有WCF,但仅仅向进程添加websockets接口是否太重?WebClient已经期望使用特定的websockets协议(而不是WCF),我可以在服务器进程和asp.net服务器之间使用套接字,但这样我就可以复制asp.net的很多功能。我希望得到像golang的易于嵌入的WebSocket这样的东西。代码看起来不错。