建设银行网站如何查询开户行,义乌网,付费阅读小说网站开发建设源码,wordpress设置全屏Yarp介绍YARP是微软开源的用来代理服务器的反向代理组件#xff0c;可实现的功能类似于nginx。基于YARP#xff0c;开发者可以非常快速的开发一个性能不错的小nginx#xff0c;用于代理http(s)请求到上游的http(s)服务。http穿透原理同网现象在http反向代理里#xff0c;代… Yarp介绍YARP是微软开源的用来代理服务器的反向代理组件可实现的功能类似于nginx。基于YARP开发者可以非常快速的开发一个性能不错的小nginx用于代理http(s)请求到上游的http(s)服务。http穿透原理同网现象在http反向代理里代理服务器总是上游服务的http客户端为了网络性能实际上上游服务总是和代理服务处在同一个局域网。试问一个问题在公网的小nginx如何把请求代理到局域网的http服务器你会发现小nginx做不到因为小nginx所在公网服务器无法直接与局域网的http服务器进行通信。http穿透在tcp里进行连接时总是由客户端发起但当连接之后客户端与服务端是平等的他们之间可以双向收发数据。只要公网小nginx与局域网的http服务器存在tcp连接我们可以使用这个连接做为httpClient的连接层然后小nginx使用这个httpClient请求到局域网http服务器而从达到http穿透效果。完整流程基于Yarp的http穿透main连接我们可以使用websocket协议创建main连接主要有以下好处共享代理服务器监听的http(s)端口利用websocket的ping-pong实现连接检测利用websocket连接请求头进行身份认证接收局域网创建的连接我们可以为kestrel编写中间件用获取获取局域网主动创建的tcp连接这些连接与代理服务器与浏览器之间的连接共享同一个服务器端口以下的listen.Use(transportService.OnConnectedAsync);是一个kestrel中间件。public static IWebHostBuilder UseKestrelTransportChannel(this IWebHostBuilder hostBuilder)
{return hostBuilder.UseKestrel(kestrel {var transportService kestrel.ApplicationServices.GetRequiredServiceTransportChannelService();var options kestrel.ApplicationServices.GetRequiredServiceIOptionsHttpMouseOptions().Value;var http options.Listen.Http;if (http ! null){kestrel.Listen(http.IPAddress, http.Port, listen {listen.Use(transportService.OnConnectedAsync);});}var https options.Listen.Https;if (https ! null File.Exists(https.Certificate.Path)){kestrel.Listen(https.IPAddress, https.Port, listen {listen.Protocols HttpProtocols.Http1AndHttp2;listen.UseHttps(https.Certificate.Path, https.Certificate.Password);listen.Use(transportService.OnConnectedAsync);});}});
}
绑定连接到HttpClientYarp进行代理时需要指定HttpMessageInvokerHttpMessageInvoker实际是SocketsHttpHandler的包装。而SocketsHttpHandler可以设置ConnectCallback属性用于指定连接。private static HttpMessageInvoker CreateHttpClient(TransportChannelService transportChannelService)
{return new HttpMessageInvoker(new SocketsHttpHandler(){UseProxy false,UseCookies false,AllowAutoRedirect false,AutomaticDecompression DecompressionMethods.None,ConnectCallback transportChannelService.CreateChannelAsync,SslOptions new SslClientAuthenticationOptions{RemoteCertificateValidationCallback delegate { return true; }}});
}
Yarp直接转发使用直接转发中间件/// summary
/// 配置中间件
/// /summary
/// param nameapp/param
/// param nameconnectionService/param
/// param namehttpForwarderService/param
public void Configure(IApplicationBuilder app, IHostEnvironment hostEnvironment, ConnectionService connectionService, HttpForwarderService httpForwarderService)
{ app.UseWebSockets();app.Use(connectionService.OnConnectedAsync);app.Use(httpForwarderService.SendAsync);
}
通过请求的域名找到局域网要转发的最终服务器地址做为yarp的请求地址。/// summary
/// 发送http数据
/// /summary
/// param namehttpContext/param
/// returns/returns
public async Task SendAsync(HttpContext httpContext, FuncTask next)
{var clientDomain httpContext.Request.Host.Host;if (this.connectionService.TryGetClientUpStream(clientDomain, out var clientUpstream)){var destPrefix clientUpstream.ToString();if (this.options.CurrentValue.HttpRequest.TryGetValue(clientDomain, out var requestConfig) false){requestConfig this.defaultRequestConfig;}await this.httpForwarder.SendAsync(httpContext, destPrefix, httpClient, requestConfig, this.transformer);}
}
总结基于kestrel和SocketsHttpHandler高度可定制化的扩展能力结合Yarp组件我们可以很方便的开发一个支持内网http穿透的公网http反向代理服务器。如果把泛域名指向公网反向代理服务器最终实现一个二级域名绑定流量到一个局域网http服务器的一对多功能。相关文章YARP实现Dapr服务调用的反向代理用YARP当网关小试YARP