Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services “信号器返回”;“需要连接ID”;在AWS ECS容器中运行时_Amazon Web Services_Asp.net Core_Signalr_Kestrel Http Server - Fatal编程技术网

Amazon web services “信号器返回”;“需要连接ID”;在AWS ECS容器中运行时

Amazon web services “信号器返回”;“需要连接ID”;在AWS ECS容器中运行时,amazon-web-services,asp.net-core,signalr,kestrel-http-server,Amazon Web Services,Asp.net Core,Signalr,Kestrel Http Server,我正试图获得一个带有角度前端的.NETCore3.1SignalerWebAPI来处理WebSocket 在本地运行时,无论是从IDE内部还是通过docker run运行,代码都可以正常运行。但是,一旦代码部署到API网关后面AWS中的ECS实例,web套接字将拒绝连接 我将映射设置为: app.UsePathBase("/ui"); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute(

我正试图获得一个带有角度前端的.NETCore3.1SignalerWebAPI来处理WebSocket

在本地运行时,无论是从IDE内部还是通过
docker run
运行,代码都可以正常运行。但是,一旦代码部署到API网关后面AWS中的ECS实例,web套接字将拒绝连接

我将映射设置为:

app.UsePathBase("/ui");
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
               "default",
              "{controller}/{action=Index}/{id?}")
             .RequireCors(PolicyName);
    endpoints.MapHub<SessionHub>("/ws/session");
    endpoints.MapHub<SessionsHub>("/ws/sessions");
});
下面的Fiddler跟踪显示初始化websocket连接的初始HTTP请求以及kestrel返回的错误。

我调整了我的web套接字中间件,以处理访问令牌,并将其连接到
控制台。编写一些我认为可能很有见地的额外调试语句:

public async Task Invoke(HttpContext httpContext)
{
    var request = httpContext.Request;
    Console.WriteLine($"Starting connection id: {httpContext.Connection.Id}");

    // web sockets cannot pass headers so we must take the access token from query param and
    // add it to the header before authentication middleware runs
    if (request.Path.StartsWithSegments("/ws", StringComparison.OrdinalIgnoreCase)
        &&
        request.Query.TryGetValue("access_token", out var accessToken))
    {
        request.Headers.Add("Authorization", $"Bearer {accessToken}");
    }

    try
    {
        var sb = new StringBuilder();
        sb.AppendLine($"Connection Id: {httpContext.Connection.Id}");
        Console.WriteLine(sb.ToString());

        await _next(httpContext);

        sb = new StringBuilder();
        sb.AppendLine($"Status code {httpContext.Response.StatusCode}"); <-- this line
        sb.AppendLine($"Connection Id: {httpContext.Connection.Id}");    <-- and this line
        Console.WriteLine(sb.ToString());
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        Console.WriteLine(e.StackTrace);
        throw;
    }
}
公共异步任务调用(HttpContext HttpContext) { var request=httpContext.request; WriteLine($“启动连接id:{httpContext.connection.id}”); //web套接字无法传递头,因此我们必须从查询参数和 //在运行身份验证中间件之前将其添加到标头 if(request.Path.StartsWithSegments(“/ws”,StringComparison.OrdinalIgnoreCase) && request.Query.TryGetValue(“access_token”,out var accessToken)) { Add(“Authorization”、$“Bearer{accessToken}”); } 尝试 { var sb=新的StringBuilder(); sb.AppendLine($“连接Id:{httpContext.Connection.Id}”); Console.WriteLine(sb.ToString()); 等待下一步(httpContext); sb=新的StringBuilder();
sb.AppendLine($“状态代码{httpContext.Response.StatusCode}”);在Azure中,您必须启用AAR关联令牌,以确保客户端位于应用程序的同一实例上。因此,发生的情况是,第一个请求将发送到一个实例,然后第二个请求将发送到另一个实例。另一个实例与初始请求无关,因此它需要一个连接ID,因为它认为这是第一个请求。因此,请查找处理“会话状态”的设置并确保状态是持久的。我猜该请求没有作为websocket请求转发到服务器,Signal认为您正在尝试使用不支持跳过协商的LongPolling。@andy只有一个容器,因此没有其他实例可供使用。@Brennan我正按照您的思路思考,但我有long Pollinging已禁用。在执行套接字升级请求时,混合中会丢失一些内容。在这种情况下,长轮询是否被禁用并不重要。“正在执行的终结点”/ws/sessions”日志表示信号器终结点正在运行,并且是您唯一一次获得“需要的连接ID”如果您点击了LongPolling或SSE代码路径,则响应为(同样,在这里禁用LongPolling并不重要)。对于websocket请求,您应该点击这些按钮的唯一原因是网关/代理未正确转发升级请求的标头。您说您使用的是AWS API网关,可能需要对websocket进行一些配置。
public async Task Invoke(HttpContext httpContext)
{
    var request = httpContext.Request;
    Console.WriteLine($"Starting connection id: {httpContext.Connection.Id}");

    // web sockets cannot pass headers so we must take the access token from query param and
    // add it to the header before authentication middleware runs
    if (request.Path.StartsWithSegments("/ws", StringComparison.OrdinalIgnoreCase)
        &&
        request.Query.TryGetValue("access_token", out var accessToken))
    {
        request.Headers.Add("Authorization", $"Bearer {accessToken}");
    }

    try
    {
        var sb = new StringBuilder();
        sb.AppendLine($"Connection Id: {httpContext.Connection.Id}");
        Console.WriteLine(sb.ToString());

        await _next(httpContext);

        sb = new StringBuilder();
        sb.AppendLine($"Status code {httpContext.Response.StatusCode}"); <-- this line
        sb.AppendLine($"Connection Id: {httpContext.Connection.Id}");    <-- and this line
        Console.WriteLine(sb.ToString());
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        Console.WriteLine(e.StackTrace);
        throw;
    }
}