3

I’m relatively new to all the intricacies of javascript so perhaps this timing issue is just my lack of understanding how to program valid javascript for event handling.

I have two SignalR hubs being used on a single page. One is a chat hub and that works 100% of the time. The other is used with with some Raphael js objects and it is the one I’m having issues with.

I have a click event on one of the raphael circle objects and when I click on it shortly after the screen is loaded my C# hub method is not called. When this happens the error in Chrome’s dev tool’s console is “SignalR: Connection must be started before data can be sent. Call .start() before .sent()” The javascript event that calls the hub cs method is always called. The strange thing is that when I wait a few seconds the cs hub method always seems to work as expected. It’s like it takes a couple seconds to load the hub events. Has anyone else ever ran into this type of scenario?

I do have my js code in $(document).ready(function() {... but I’m guessing that because the Raphael js objects are not part of the dom until the js code is ran, it would not force them to load.

$(document).ready(function() {
    var clientHub = $.connection.tableHub;

    var canvas = Raphael((innerWidth / 2) + 83, (innerHeight / 2) - 194, 74, 74);
    var circle1 = seat1Canvas.circle(37, 37, 35);
    var circle1Text = seat1Canvas.text(37, 37, "Open");

    var buildCircleAndSendToClients = function() {
        clientHub.buildCircle(identity.Name);
    };

    var drawAvailableCircle = function() {
        circle1 = seat1Canvas.circle(37, 37, 35);
        circle1Text = seat1Canvas.text(37, 37, "Sit\nHere");
        circle1.attr("fill", "#fffeee");
        circle1.attr("stroke", "black");
        circle1.attr("stroke-width", 3);
        circle1.mousedown(buildCircleAndSendToClients);
    };

    circle1.attr("fill", "#eeefff");
    circle1.attr("stroke", "black");
    circle1.attr("stroke-width", 3);
    circle1.mouseover(drawAvailableCircle);

    clientHub.drawCircle = function(username) {
        circle1 = seat1Canvas.circle(37, 37, 35);
        circle1Text = seat1Canvas.text(37, 37, username);
        circle1.attr("fill", "#eeefff");
        circle1.attr("stroke", "black");
        circle1.attr("stroke-width", 3);
    };

    $.connection.hub.start();
});
4

1 回答 1

5

You need to move your wireup for handlers that will interact with the SignalR connection into a callback function that you pass as a parameter to the start method. This will ensure the handlers aren't active until the hub connection has started. You might want to alter the UI slightly too until that callback runs, eg have the buttons be disabled by default and only enable them once the handlers are wired up.

E.g:

$.connection.hub.start(function() { // wireup handlers and enable UI here });

于 2011-12-18T22:13:18.320 回答