1. Accept:*/* 2. Accept-Encoding:gzip, deflate 3. Accept-Language:zh-CN,zh;q=0.9,en;q=0.8 4. Cache-Control:no-cache 5. Connection:keep-alive 6. Cookie:.AUTH=A24BADC9D552CF1157B7842F2A6C159A681CA330DBB449568896FAC839CFEE51F42973C9A5B9F632418FB82C128A8BF612D27C2EE7DABDE985E9A79DF19A955FFED9E8219853FB90574B0990DD29B2B7ED23A7C26B8AD1934870B8C0FCB4F577636E267003E6D214D9B319A4739D3716E2A8299C35E228F96EC12A29CCDE83A7D2D3B24EE6A84CF2D69D81A44E0F46EC9B112BDAA9FC0E0943DB36C1449FD79E6D5A123E5D182D2C3A03D4049CBD76947D33EB5DCCE82CB1C91ACACD83B6D07F19A6629732FA16D08443450DC2937C7CEF6A2FAE941760C79064C7A5A67E844ABDA2DE89E5B10F3B30B8A89CEDE9C00A3C79711D 7. Host:erp-dev.holderzone.cn:90 8. Pragma:no-cache 9. Referer:http://erp-dev.holderzone.cn:90/ 10. User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
namespace DotEasy.Rpc.ApiGateway { public static class OcelotPipelineConfigurationExtensions { public static void AddRpcMiddleware(this OcelotPipelineConfiguration config) { config.MapWhenOcelotPipeline.Add(builder => builder.AddRpcMiddleware()); } private static Func<DownstreamContext, bool> AddRpcMiddleware(this IOcelotPipelineBuilder builder) { builder.UseHttpHeadersTransformationMiddleware(); builder.UseDownstreamRequestInitialiser(); builder.UseRateLimiting(); builder.UseRequestIdMiddleware(); builder.UseDownstreamUrlCreatorMiddleware(); builder.UseRpcRequesterMiddleware(); return context => context.DownstreamReRoute.DownstreamScheme.Equals("tcp", StringComparison.OrdinalIgnoreCase); } } }
using Ocelot.Middleware.Pipeline; namespace DotEasy.Rpc.ApiGateway { public static class RpcRequesterMiddlewareExtensions { public static void UseRpcRequesterMiddleware(this IOcelotPipelineBuilder builder) { builder.UseMiddleware<RelayRequesterMiddleware>(); } } }
using System; using System.Net; using System.Threading.Tasks; using Ocelot.Logging; using Ocelot.Middleware; namespace DotEasy.Rpc.ApiGateway { public class RelayRequesterMiddleware : OcelotMiddleware { private readonly OcelotRequestDelegate _next; private readonly IOcelotLogger _logger; public RelayRequesterMiddleware(OcelotRequestDelegate next, IOcelotLoggerFactory loggerFactory) : base(loggerFactory .CreateLogger<RelayRequesterMiddleware>()) { _next = next; _logger = loggerFactory.CreateLogger<RelayRequesterMiddleware>(); } public async Task Invoke(DownstreamContext context) { var httpContent = ... // TODO:協議轉換處理等操做 context.DownstreamResponse = new DownstreamResponse(httpContent, HttpStatusCode.OK, context.DownstreamRequest.Headers); await _next.Invoke(context); } } }
app.UseOcelot(pipelineConfiguration => pipelineConfiguration.AddRpcMiddleware()).Wait();
以上便完成了對Ocelot中DownstreamContext的擴展,html
總結下來,當咱們須要擴展下游協議時,咱們須要手動配置OcelotPipelineConfiguration並添加到IOcelotPipelineBuilder中,而後經過擴展IOcelotPipelineBuilder實現下游中間件的自定義處理。api
var httpContent = relayHttpRouteRpc.HttpRouteRpc(ClientProxy.GenerateAll(new Uri("http://127.0.0.1:8500")), new Uri(context.DownstreamRequest.ToUri()), context.DownstreamRequest.Headers); // 目前還沒有處理Headers消息頭
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using DotEasy.Rpc.Core.Runtime.Client; using DotEasy.Rpc.Core.Runtime.Communally.Convertibles; using Newtonsoft.Json; namespace DotEasy.Rpc.Core.ApiGateway.Impl { public class DefaultRelayHttpRouteRpc : IRelayHttpRouteRpc { private IRemoteInvokeService _remoteInvokeService; private ITypeConvertibleService _typeConvertibleService; public DefaultRelayHttpRouteRpc(IRemoteInvokeService remoteInvokeService, ITypeConvertibleService typeConvertibleService) { _remoteInvokeService = remoteInvokeService; _typeConvertibleService = typeConvertibleService; } public StringContent HttpRouteRpc(List<dynamic> proxys, Uri urlPath, HttpRequestHeaders headers) { foreach (var proxy in proxys) { Type type = proxy.GetType(); if (!urlPath.Query.Contains("scheme=rpc")) continue; var predicate = urlPath.AbsolutePath.Split('/'); var absName = predicate[predicate.Length - 1]; var absPars = predicate[predicate.Length - 2]; if (!type.GetMethods().Any(methodInfo => methodInfo.Name.Contains(absName))) continue; var method = type.GetMethod(absName); if (method != null) { var parameters = method.GetParameters(); var parType = parameters[0].ParameterType; // only one parameter var par = _typeConvertibleService.Convert(absPars, parType); var relayScriptor = new RelayScriptor {InvokeType = type, InvokeParameter = new dynamic[] {par}}; var result = method.Invoke( Activator.CreateInstance(relayScriptor.InvokeType, _remoteInvokeService, _typeConvertibleService), relayScriptor.InvokeParameter); var strResult = JsonConvert.SerializeObject(result); return new StringContent(strResult); } } return null; } } }