0

我正在开发一个应用程序,以使用 SignalR 在多个 Web 托管应用程序之间执行上下文同步。客户端机器使用 SignalR Owin 主机实例化主机,应用程序使用 JS 客户端的无代理版本连接到它。我遇到的问题是“客户端”应用程序托管在 SSL 环境中,而 SignalR 主机不是(因为它受限于本地机器)。如果我尝试从托管 javascript 客户端的标准非 SSL 网站连接到集线器,一切正常。一旦我将客户端加载到 SSL 网站,但是当我尝试启动连接时,我会收到“SignalR:协商请求期间错误:未定义”。有人知道解决这个问题的方法吗?

主持人:

    public class SignalRHost : IDisposable
{
    private IDisposable _webApp;

    public SignalRHost(string url = "http://localhost:9000/")
    {
        _webApp = WebApplication.Start<Startup>(url);
    }

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            bool enableErrorDetail = false;
#if DEBUG
            enableErrorDetail = true;
#endif
            app.MapHubs(new HubConfiguration { EnableCrossDomain = true, EnableDetailedErrors = enableErrorDetail });
        }

    }


    public void Dispose()
    {
        _webApp.Dispose();
    }
}

JS客户端:

    (function (ns_HubClient) {
    ns_HubClient.connection;
    ns_HubClient.proxy;

    ns_HubClient.initialize = function () {
        ns_HubClient.connection = $.hubConnection("http://localhost:9000");
        ns_HubClient.proxy = ns_HubClient.connection.createHubProxy("fluencyHub");

        ns_HubClient.proxy.on('addMessage', function (data) { ns_HubClient.processMessage(data); });


        ns_HubClient.connection.start()
            .done(function () {
                alert("connection complete");
            })
            .fail(function (data) {
                alert("connection start failed: " + data);
            });
    };

    ns_HubClient.login = function (sUserName, sPassword, sDomain) {
        var fluencyMessage = {
            MessageId: "",
            CallType: "Asynchronous",
            Method: "Login",
            Status: "",
            Response: {},
            Request: {
                sUserName: sUserName,
                sPassword: sPassword,
                sDomain: sDomain
            }
        };

        ns_HubClient.sendMessage(fluencyMessage);
    };

    ns_HubClient.writeLog = function (message, errorLevel) {
        var logMessage = {
            ErrorLevel: errorLevel,
            Message: message
        };
        ns_HubClient.proxy.invoke("logMessage", logMessage);
    };

    ns_HubClient.processMessage = function (message) {

    };

    ns_HubClient.sendMessage = function (data) {
        ns_HubClient.proxy.invoke("addMessage", data);
    };

} (window.ns_HubClient = window.ns_HubClient || {}));
4

1 回答 1

2

SignalR JS 客户端创建一个 XHR 来“协商”应该使用哪些传输(例如 WebSocket)来与 SignalR 服务器建立双向通信等。

浏览器供应商可以选择不允许从 HTTPS 页面到 HTTP 资源的 XHR:http: //www.w3.org/TR/access-control/#user-agent-security

请注意第四个要点:“允许用户代理终止算法而不发出请求。这可以这样做,因为例如:...。不允许 https 到 http。”

浏览器供应商可能会选择这样做,因为不安全的 XHR 会使原本安全的 Web 应用程序容易受到中间人攻击。

我会使用您浏览器的 F12 工具或使用像fidler这样的 HTTP 代理来验证浏览器实际上是在发出“协商”请求。如果是,您可以查看响应以帮助弄清楚发生了什么。

于 2013-02-27T20:33:20.470 回答