2
votes

I've got some kind of basic config issue trying to get my first SignalR app working. It's generating a proxy, but there's no hub in it, and I can't even call createHubProxy(), that function doesn't exist in my proxy for some reason.

I'm calling RouteTable.Routes.MapHubs() in Application_start, I tried setting in web.config as well. What am I doing wrong?

This is a plain 'ol Web Forms app. My aspx code:

<%@ Page Language="C#" CodeFile="blogroll3.aspx.cs" Inherits="blogroll3" %>

<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.2.min.js"></script>
    <script src="/scripts/jquery.signalR-1.1.3.js"></script>
    <script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script>
<script src="blogroll3.js"></script>
</head>
<body>
</body>
</html>

codebehind:

using System;
using System.Web.UI;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

public partial class blogroll3 : Page
{
    public class ProgressHub : Hub
    {
        public void setProgress()
        {
        }
    }
}

my client js code:

//this is not working, progressHub is undefined:
//var proghub = $.connection.progressHub;

//this code fails on createHubProxy(), it doesn't exist.
var connection = $.hubConnection();
var proghub = $.connection.createHubProxy('progressHub');

Here's the proxy it's generating:

/*!
 * ASP.NET SignalR JavaScript Library v1.1.3
 * http://signalr.net/
 *
 * Copyright Microsoft Open Technologies, Inc. All rights reserved.
 * Licensed under the Apache 2.0
 * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
 *
 */

/// <reference path="..\..\SignalR.Client.JS\Scripts\jquery-1.6.4.js" />
/// <reference path="jquery.signalR.js" />
(function ($, window) {
    /// <param name="$" type="jQuery" />
    "use strict";

    if (typeof ($.signalR) !== "function") {
        throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/hubs.");
    }

    var signalR = $.signalR;

    function makeProxyCallback(hub, callback) {
        return function () {
            // Call the client hub method
            callback.apply(hub, $.makeArray(arguments));
        };
    }

    function registerHubProxies(instance, shouldSubscribe) {
        var key, hub, memberKey, memberValue, subscriptionMethod;

        for (key in instance) {
            if (instance.hasOwnProperty(key)) {
                hub = instance[key];

                if (!(hub.hubName)) {
                    // Not a client hub
                    continue;
                }

                if (shouldSubscribe) {
                    // We want to subscribe to the hub events
                    subscriptionMethod = hub.on;
                }
                else {
                    // We want to unsubscribe from the hub events
                    subscriptionMethod = hub.off;
                }

                // Loop through all members on the hub and find client hub functions to subscribe/unsubscribe
                for (memberKey in hub.client) {
                    if (hub.client.hasOwnProperty(memberKey)) {
                        memberValue = hub.client[memberKey];

                        if (!$.isFunction(memberValue)) {
                            // Not a client hub function
                            continue;
                        }

                        subscriptionMethod.call(hub, memberKey, makeProxyCallback(hub, memberValue));
                    }
                }
            }
        }
    }

    $.hubConnection.prototype.createHubProxies = function () {
        var proxies = {};
        this.starting(function () {
            // Register the hub proxies as subscribed
            // (instance, shouldSubscribe)
            registerHubProxies(proxies, true);

            this._registerSubscribedHubs();
        }).disconnected(function () {
            // Unsubscribe all hub proxies when we "disconnect".  This is to ensure that we do not re-add functional call backs.
            // (instance, shouldSubscribe)
            registerHubProxies(proxies, false);
        });



        return proxies;
    };

    signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
    $.extend(signalR, signalR.hub.createHubProxies());

}(window.jQuery, window));
4
Your code looks alright I tried it pretty much 100% the same and it worked for me. Is your Hub class in the same process/app domain as your SignalR server?N. Taylor Mullen
I think I figured it out just a minute ago. Moving the Hub class out of the page class fixed the problem. Which makes sense now that I think about it :\ So I moved it to a new class in my App_Code folder and now my proxy classes are being generated. I guess the hub proxy won't be complete if the hub is a subclass of something else.Eric Sassaman
When I tried your code I also put a hub class inside a Page. I agree odd and I didn't think it would work when I tried it but it did so something else must have been contributing to it. Nonetheless glad it's fixed :)N. Taylor Mullen
I would expect nested Hubs to work as long as they are fully public.halter73
From the API ref, "SignalR creates a new instance of your Hub class each time it needs to handle a Hub operation such as when a client connects, disconnects, or makes a method call to the server" and this can't be done if my hub class is nested in another class, is that right? But if you got it to work... hmmmm. In the end, ripping it out of the Page forced me to refactor it in such a way that it's much more reuseable as an external class anyways, so it all worked out better in the end. Still I'd like to know if that was my problem or not...Eric Sassaman

4 Answers

2
votes

1) Make sure the section: @Scripts.Render("~/bundles/jquery") gets called before the latest signalr js file: jquery.signalR-2.0.2.min.js

2) If you use a layout page move the @Scripts.Render("~/bundles/jquery") to the header section.

3) Also make sure you are referencing the latest version of signal-r - at the time of writing: jquery.signalR-2.0.2.min.js

0
votes

The problems was that my Hub class was nested in my Page class. Moving it out solved the problem. See comments to my original question.

0
votes

all i ended up doing was pulling up that dynamic script in the browser

http://my app base url/signalr/hubs

then when the source came up i went through these steps

  1. CTRL+A
  2. CTRL+C
  3. create file hubs.js
  4. CTRL+V
  5. substitute /signalr/hubs with /hubs.js

might be barbaric and overly simple. but, it's working for me

0
votes

Use uppercase letters for signalR R.

For example:

<script src="@Href("~/Scripts/jquery.signalR.js")" type="text/javascript"></script>

Instead of:

<script src="@Href("~/Scripts/jquery.signalr.js")" type="text/javascript"></script>