我有两个Restful API项目,它们试图合并到一个应用程序项目(新的.net核心之一)中,我修改了Running multiple independent ASP.NET Core pipelines side by side in the same application中的代码以接受WebSockets,如下扩展方法所示:
public static IApplicationBuilder UseBranchWithServices(
this IApplicationBuilder app,
PathString path,
Type requiredStartup) {
var webHost = WebHost.CreateDefaultBuilder()
.UseStartup(requiredStartup).Build();
var serviceProvider = webHost.Services;
var serverFeatures = webHost.ServerFeatures;
var appBuilderFactory =
serviceProvider.GetRequiredService<IApplicationBuilderFactory>();
var branchBuilder = appBuilderFactory.CreateBuilder(serverFeatures);
var factory = serviceProvider.GetRequiredService<IServiceScopeFactory>();
if (path.Value.Contains("/project2")) {
branchBuilder.Map(
"/project2/ws",
x =>
x.UseMiddleware<project2MicroService.WebSockets.WebSocketMiddleWare>(
serviceProvider.GetService<SceneWebSocketHandler>()));
} else if (path.Value.Contains("/project1")) {
branchBuilder.Map(
"/project1/ws",
x => x.UseMiddleware<project1Service.WebSockets.WebSocketMiddleWare>(
serviceProvider.GetService<project1WebSocketHandler>()));
}
var branchDelegate = branchBuilder.Build();
return app.Map(
path,
builder => {
builder.Use(
async (context, next) => {
if (!context.WebSockets.IsWebSocketRequest) {
await branchDelegate(context).ConfigureAwait(false);
} else {
await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
await branchDelegate(context).ConfigureAwait(false);
}
});
});
}
我在新应用程序中将其称为
app.UseBranchWithServices("/project2", typeof(project2MicroService.Startup));
在运行单元测试时,WebSocket连接被接受,但中间件从未被点击 任何想法如何解决这个问题,请进行我的单元测试
[ClassInitialize]
public static void TestOneTimeSetUp(TestContext context) {
var webHostBuilder = WebHost.CreateDefaultBuilder();
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory());
webHostBuilder.UseStartup<Startup>();
server = new TestServer(webHostBuilder);
client = server.CreateWebSocketClient();
}
/// <summary>
/// OneTimeTearDown
/// </summary>
[ClassCleanup]
public static void TestOneTimeTeardown() {
server.Dispose();
}
/// <summary>
/// TestWebsocketCanBeCreated
/// </summary>
[TestMethod]
public void TestWebsocketCanBeCreated() {
var TEST1wsUri = new UriBuilder(server.BaseAddress + "project1/ws") { Scheme = "ws" }.Uri;
var TEST1websocket = client.ConnectAsync(TEST1wsUri, CancellationToken.None).Result;
var TEST2wsUri = new UriBuilder(server.BaseAddress + "project2/ws") { Scheme = "ws" }.Uri;
var TEST2websocket = client.ConnectAsync(TEST2wsUri, CancellationToken.None).Result;
Assert.AreEqual(WebSocketState.Open, TEST2websocket.State);
Assert.AreEqual(WebSocketState.Open, TEST1websocket.State);
Task.WaitAll(
TEST1websocket.CloseAsync(
WebSocketCloseStatus.NormalClosure,
"",
CancellationToken.None));
Task.WaitAll(
TEST2websocket.CloseAsync(
WebSocketCloseStatus.NormalClosure,
"",
CancellationToken.None));
Assert.AreEqual(WebSocketState.Closed, TEST2websocket.State);
Assert.AreEqual(WebSocketState.Closed, TEST1websocket.State);
}
答案 0 :(得分:4)
您做错了几件事:
1)您正在尝试使用if / else逻辑定义路由行为。不要那样做。 2)您实际上并没有在声明要作为管道一部分的内容。考虑以下内容:
// https://stackoverflow.com/questions/48216929/how-to-configure-asp-net-core-server-routing-for-multiple-spas-hosted-with-spase
app.Map("/rx", rx => {
rx.UseSpa(rxApp => {
rxApp.Options.SourcePath = "../RX";
if (envIsDevelopment) rxApp.UseProxyToSpaDevelopmentServer("http://localhost:3000");
});
});
app.Map("/V2", ng => {
// https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/angular?view=aspnetcore-2.2
app.UseSpa(angularApp =>
{
angularApp.Options.SourcePath = "../UI";
if (envIsDevelopment) angularApp.UseProxyToSpaDevelopmentServer("http://localhost:4200");
});
});
请注意那里的链接:Filip W.'s blog
这是一个不同的用例,但这是如何将两条不同的路线映射到不同目的地的示例。您正在尝试打开URL,但这不是管道的工作方式。这是一个声明式管道;您必须根据.NET Core的内置插件定义路由(或添加包含其他中间件插件的依赖项)。
在这里看看:
...而且不要重新发明轮子。
答案 1 :(得分:2)
我查看了您得到的解决方案,但对我而言不起作用。因此,我们为此创建了一个解决方案,该解决方案完全可以完成您想要的工作,并且可以长时间无缝地工作。
https://github.com/damianh/AspNetCoreNestedApps/tree/master/AspNetCoreNestedApps3
如果我总结代码;
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.IsolatedMap<NestedStartup>("/nested");
app.IsolatedMap<XApp>("/xroute");
app.Run(async context => await context.Response.WriteAsync("Hello World!"));
}
您可以基于Startup
分离应用程序并轻松路由。但是,请记住,某些事情可能不适用于管道,因为您是在构建主容器之后进行分支的。我们介绍了分支机构的托管服务。