【问题标题】:How to scale SignalR using Azure Worker Role and OWIN如何使用 Azure Worker Role 和 OWIN 扩展 SignalR
【发布时间】:2014-04-24 09:52:14
【问题描述】:

SignalR 使用 Azure Web 角色进行了惊人的扩展。但是,当我在 Azure 辅助角色中使用自托管 OWIN 项目时,当添加多个实例时,SignalR 将开始出现问题。作为记录,我的项目使用 Redis 作为背板。

当 Azure Worker Role 实例增加到一个以上时,客户端连接将随机失败,并出现错误“ConnectionId 格式不正确”。我相信这是由于负载平衡导致单个客户端的协商跨越多个服务器时引起的;我不相信参与协商的多个服务器可以解密数据(隐藏的 DPAPI?)。

我尝试在 app.config 中设置 validationKey 和 decryptionKey 但这似乎没有什么不同;问题依然存在。同样,该项目可以作为 Web 角色 (IIS) 正常工作,但不能作为 Worker 角色(OWIN 自托管)。

假设这是 DpapiDataProtectionProvider 的问题,我如何确保提供程序在多个服务器/实例之间呈现相同的加密/解密结果?

解决方案

SignalR 使用的默认保护提供程序 (DpapiDataProtectionProvider) 似乎不支持 Azure Worker Role 横向扩展。通过滚动我自己的示例提供程序,我能够扩展 SignalR/OWIN/Azure Worker,并且不会收到随机的 400 HTTP/“ConnectionId 格式不正确”。请记住,以下示例不会保护/保护令牌。

public class ExampleDataProvider : IDataProtector
{
    public byte[] Protect(byte[] userData)
    {
        Trace.TraceInformation("Protect called: " + Convert.ToBase64String(userData));
        return userData;
    }

    public byte[] Unprotect(byte[] protectedData)
    {
        Trace.TraceInformation("Unprotect called: " + Convert.ToBase64String(protectedData));
        return protectedData;
    }
}

public class ExampleProtectionProvider : IDataProtectionProvider
{
    public IDataProtector Create(params string[] purposes)
    {
        Trace.TraceInformation("Example Protection Provider Created");
        return new ExampleDataProvider();
    }
}

在 Owin 启动期间注入自定义提供程序:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.SetDataProtectionProvider(new ExampleProtectionProvider());

        GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration("0.0.0.0", 0, "", "Example"));

        app.MapSignalR(new HubConfiguration
        {
            EnableDetailedErrors = true
        });

        app.UseWelcomePage("/");
    }
}

【问题讨论】:

    标签: c# redis signalr dpapi


    【解决方案1】:

    SignalR 使用来自 IAppBuilder.Properties["security.DataProtectionProvider"] 的 IDataProtectionProvider(如果它不为空)。

    在调用 MapSignalR 之前,您可以在 Startup.Configuration 中将其替换为您自己的 IDataProtectionProvider。

    通过为您提供自己的 IDataProtectionProvider,您可以确保每个工作角色使用相同的密钥来保护/取消保护。

    【讨论】:

    • 谢谢,成功了!我添加了一个自定义 IDataProtectionProvider(以及生成的 IDataProtector),并且能够在没有获得 HTTP 400/“ConnectionId 格式不正确”的情况下扩展 Worker 角色。因此,默认提供程序 (DpapiDataProtectionProvider) 对农场不友好。
    猜你喜欢
    • 1970-01-01
    • 2013-12-03
    • 2015-03-17
    • 1970-01-01
    • 2015-02-06
    • 2015-03-17
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多