Asynchronous 在Asp Net核心服务中运行异步方法的位置

Asynchronous 在Asp Net核心服务中运行异步方法的位置,asynchronous,.net-core,Asynchronous,.net Core,我有一个服务,它必须保持与数据库的实时连接。这个连接必须在任何客户端请求之前实例化 由于数据库API提供了一种异步连接方法,在发出任何请求之前,我在哪里可以连接到数据库 SocketMiddleware: class SocketMiddleware { Handler handler; public SocketMiddleware(Handler _handler,RequestDelegate del) { t

我有一个服务,它必须保持与数据库的实时连接。这个连接必须在任何客户端请求之前实例化

由于数据库API提供了一种异步连接方法,在发出任何请求之前,我在哪里可以连接到数据库

SocketMiddleware

class SocketMiddleware
    {
        Handler handler;
        public SocketMiddleware(Handler _handler,RequestDelegate del)
        {
            this.handler = _handler;
            this.next = del;
        }

        RequestDelegate next;

        public async Task Invoke(HttpContext context)
        {

            if (!context.WebSockets.IsWebSocketRequest)
            {
                await  this.next(context);
                return;
            }
            await this.handler.AddClientAsync(context.WebSockets);

        }
    }
使用实时
DB
连接的服务

 class Handler
        {

            private readonly RethinkDB r;
            public  Connection Con { get; private set; }

            private ConcurrentDictionary<string, Client> clients = new ConcurrentDictionary<string, Client>();
            private object Lock = new object();

            public Handler()
            {
                this.r = new RethinkDB();
               //I have to instnatiate --- this.Con = this.r.Connection().Port(Constants.RETHINK_PORT).Hostname(Constants.HOST_NAME).ConnectAsync();
            }
              ///////////////////////////---Where can i run the below method?
            public async Task ConnectRethinkAsync()
            {
                using (Process proc = new Process())
                {
                    proc.StartInfo = new ProcessStartInfo(Constants.RETHINK_PROCESS_PATH);
                    proc.Start();


                    this.Con = await this.r.Connection().Port(Constants.RETHINK_PORT).Hostname(Constants.HOST_NAME).ConnectAsync();
                }

            }
            public async Task AddClientAsync(WebSocketManager manager)
            {
                WebSocket clientSocket = await manager.AcceptWebSocketAsync();
                string clientID = Ext.MakeId();
                using (Client newClient = Client.Create(clientSocket, clientID))
                {

                    while (true)
                    {
                        if (!newClient.KeepAlive)
                        {
                            break;
                        }
                        ReadOnlyMemory<byte>received = await newClient.ReceiveAsync();
                        string toSend =  $"From Server:\r\nDate:{DateTime.Now.ToString()},WasReceived:{Encoding.UTF8.GetString(received.ToArray())}\r\nEnd of Message\r\n";
                       // await r.Db(Constants.DB_NAME).Table(Constants.TABLE_NAME).RunAsync(this.Con);
                        await newClient.SendAsync(toSend);
                    }
                }



            }
            public bool RemoveClient(string ID)
            {
                if (this.clients.TryRemove(ID, out Client value))
                {
                    value.Dispose();
                    return true;
                }
                return false;

            }

        }
类处理程序
{
私有只读数据库;
公共连接Con{get;private set;}
私有ConcurrentDictionary客户端=新建ConcurrentDictionary();
私有对象锁=新对象();
公共处理程序()
{
this.r=newdb();
//我必须安装--this.Con=this.r.Connection().Port(常数.重新思考端口).主机名(常数.主机名).ConnectAsync();
}
///////////////////////////---在哪里可以运行下面的方法?
公共异步任务ConnectAsync()
{
使用(Process proc=new Process())
{
proc.StartInfo=新进程StartInfo(常数.重新思考进程路径);
proc.Start();
this.Con=wait this.r.Connection().Port(Constants.reference_Port)、Hostname(Constants.HOST_NAME)、ConnectAsync();
}
}
公共异步任务AddClientAsync(WebSocketManager)
{
WebSocket clientSocket=await manager.AcceptWebSocketAsync();
字符串clientID=Ext.MakeId();
使用(Client newClient=Client.Create(clientSocket,clientID))
{
while(true)
{
如果(!newClient.KeepAlive)
{
打破
}
ReadOnlyMemoryreceived=Wait newClient.ReceiveAsync();
string toSend=$“来自服务器:\r\n数据:{DateTime.Now.ToString()},wasserved:{Encoding.UTF8.GetString(received.ToArray())}\r\n消息的名称\r\n”;
//等待r.Db(Constants.Db_NAME).Table(Constants.Table_NAME).RunAsync(this.Con);
等待newClient.SendAsync(toSend);
}
}
}
public bool RemoveClient(字符串ID)
{
if(this.clients.TryRemove(ID,out客户端值))
{
value.Dispose();
返回true;
}
返回false;
}
}
注意:在上面的代码片段中,最重要的一行是带有注释的一行:我需要实例化连接,这是一个异步操作。
我不能在
处理程序中实例化它,也不在
SocketMiddleware
ctor中。
在执行任何请求之前必须初始化
Con
。(在本例中,调用了
addclientsync

数据库连接是否应该在其他服务中完成?

因为您已经保护了要从外部设置的连接,所以可以在
addclientsync
中恢复连接,如:

if(this.Con == null)
{
    this.Con = await this.r.Connection()
           .Port(Constants.RETHINK_PORT)
           .Hostname(Constants.HOST_NAME)
           .ConnectAsync();
}

使用目标方法初始化连接。它将在第一次调用时初始化,并在后续调用时返回连接。你说的懒惰是什么意思?除非调用其
连接.ConnectAsync
方法,否则它是空的。方法
端口
主机名
返回的对象不是
连接
类型。只有在运行
ConnectAsync
时,我才能获得
连接
,以及我创建的包装器方法除了我不想/不需要的每一个客户端请求之外,没有地方可以调用连接。但我不想污染
AddClientSync
域,因为这是另一个问题。在创建
处理程序时,数据库的
连接
只执行一次,而
AddClientSync
则对每个客户端执行一次
websocket
accept。在
处理程序
类中是否没有其他地方可以插入
连接
(可能在
Startup
类的层次结构中更高,特别是在
Configure
ConfigureServices
中?我这样问是因为将来
处理程序可能需要其他依赖项才能正常工作。然后我要做的是将连接逻辑重构为它自己的异步方法。然后你可以所有这些都来自
handler.addClientSync
之前的中间件,但这仍然会将其与
Invoke
方法中的每个HTTP/TCP请求相耦合。我仍然需要在每个
Invoke()
调用中放置一点得到计算的
if()…
。if语句可以在新连接方法中