【问题标题】:.NET Core reverse proxy middleware and signalR.NET Core 反向代理中间件和 signalR
【发布时间】:2021-05-26 05:44:25
【问题描述】:

我需要在 ASP.NET Core 中做一个反向代理中间件。我有这样的东西。但它不适用于 SignalR。

反向代理的地址为 192.168.187.72:5000; SignalR 192.168.187.62:5000。客户端连接到代理,代理将 url 更改为 SignalR hub url,但在客户端我总是收到此错误:

在握手开始之前服务器断开了

代码:

public ReverseProxyMiddleware(RequestDelegate nextMiddleware,ILogger<ReverseProxyMiddleware> logger)
{
    _nextMiddleware = nextMiddleware;
    _logger = logger;
}

public async Task Invoke(HttpContext context)
{
     var targetUri = BuildTargetUri(context.Request);
       
     if (targetUri != null)
     {
         var targetRequestMessage = CreateTargetMessage(context, targetUri);
           
         using (var responseMessage = await _httpClient.SendAsync(targetRequestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
         {
             context.Response.StatusCode = (int)responseMessage.StatusCode;
                
             CopyFromTargetResponseHeaders(context, responseMessage);
             await responseMessage.Content.CopyToAsync(context.Response.Body);
         }

         return;
    }

    await _nextMiddleware(context);
}

private HttpRequestMessage CreateTargetMessage(HttpContext context, Uri targetUri)
{
    var requestMessage = new HttpRequestMessage();

    CopyFromOriginalRequestContentAndHeaders(context, requestMessage);

    requestMessage.RequestUri = targetUri;
    requestMessage.Headers.Host = targetUri.Host;
    requestMessage.Method = GetMethod(context.Request.Method);

    return requestMessage;
}

private void CopyFromOriginalRequestContentAndHeaders(HttpContext context, HttpRequestMessage requestMessage)
{
    var requestMethod = context.Request.Method;
       
    var streamContent = new StreamContent(context.Request.Body);
    requestMessage.Content = streamContent;

    foreach (var header in context.Request.Headers)
    {
        requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
    }
}

private void CopyFromTargetResponseHeaders(HttpContext context, HttpResponseMessage responseMessage)
{
    foreach (var header in responseMessage.Headers)
    {
        context.Response.Headers[header.Key] = header.Value.ToArray();
    }

    foreach (var header in responseMessage.Content.Headers)
    {
        context.Response.Headers[header.Key] = header.Value.ToArray();
    }

    context.Response.Headers.Remove("transfer-encoding");
}

private static HttpMethod GetMethod(string method)
{
    if (HttpMethods.IsDelete(method)) return HttpMethod.Delete;
    if (HttpMethods.IsGet(method)) return HttpMethod.Get;
    if (HttpMethods.IsHead(method)) return HttpMethod.Head;
    if (HttpMethods.IsOptions(method)) return HttpMethod.Options;
    if (HttpMethods.IsPost(method)) return HttpMethod.Post;
    if (HttpMethods.IsPut(method)) return HttpMethod.Put;
    if (HttpMethods.IsTrace(method)) return HttpMethod.Trace;

    return new HttpMethod(method);
}

private Uri BuildTargetUri(HttpRequest request)
{
    Uri targetUri = null;
    StringValues clientId = string.Empty;

    targetUri = new Uri($"http://192.168.187.62:5000{request.Path}{request.QueryString}");

    _logger.LogInformation($"Request URL {request.Host + request.Path + request.QueryString} Target URL {targetUri.ToString()}");

    return targetUri;
}

【问题讨论】:

    标签: asp.net reverse-proxy


    【解决方案1】:

    您确定要手动创建此类功能吗?

    有许多很棒的反向代理库,微软有一个名为 YARP (https://microsoft.github.io/reverse-proxy/) 的新项目,它是一个开源反向代理,被告知具有高性能和高度可定制性。

    如果您愿意,我可以向您展示如何在 ASP.NET Core 应用程序中使用 yarp。

    【讨论】:

    • 会很棒,我用 signalR 试过了,但是出了点问题。
    • 我有使用 YARP 并使用 signalR 的应用程序,它确实支持它。你能展示你的路由配置和中间件管道吗?
    • 集群目标地址应以“/”字符结尾。同样在此配置中,如果您的客户端连接到 192.168.187.72:5000/signalrClincHub,代理将重新路由到 192.168.187.62:5000/signalrClincHub/signalrClincHub(重复路由部分),这是故意的吗?
    • pastebin.pl/view/38046242 这对我有用。我尝试添加标头路由,但所有请求都没有发生,不仅像我预期的那样使用标头,你能检查一下吗?
    • 标题过滤器在我看来没问题,你还有其他路线吗?也许其他请求通过了,因为您在此之后定义了其他路由。
    猜你喜欢
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2019-02-22
    • 2020-05-01
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多