最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - SignalR: Hub OnConnected not called if no client methods - Stack Overflow

programmeradmin6浏览0评论

I am writing a game in SignalR. The idea is that you connect with your laptop, which will be used as "display" and then you connect with your smart phone and that will be used as "joystick". The entire setup works very well.

Now that it all works, I decided to refactor the code. I realized that the relationship between the joystick and the display is one way (the display never needs to send information back to the joystick). Therefore I decided that I did not need any signalR invokable client functions on the joystick (e.g. there is no use for gameHub.client.joyStickMethod() in the joystick js.

It was then I discovered something strange

It turns out that hub method public override Task OnConnected() that I override to deal with the different types of clients (displays and joysticks) is not invoked unless I define a myHub.client.clientSideMethod(). Here's the example I'm dealing with:

        var gameHub = $.connection.gameHub;
        gameHub.client.connection();
        $("#joystick").joystick({
            hub: gameHub
        });

        gameHub.client.activateJoystick = function () { };
        $.connection.hub.qs = "type=joystick&gameId=" + "@Model.Id";
        $.connection.hub.start();   //this will invoke on connected

You see that empty client side method? That's the reason why OnConnected is called on server side. If I remove that line of code, it will not be called.

        var gameHub = $.connection.gameHub;
        gameHub.client.connection();
        $("#joystick").joystick({
            hub: gameHub 
        });

        //gameHub.client.activateJoystick = function () { };
        $.connection.hub.qs = "type=joystick&gameId=" + "@Model.Id";
        $.connection.hub.start();   //this will invoke on connected

This will not work, since there is no client side method on the Hub. I can probably add a RegistrateJoystickmethod on the Hub and call that, but I think that the behavior is unexpected. My question is therefore:

Is there a way to manually "connect" to the hub, so that the OnConnect method will be called?

I am writing a game in SignalR. The idea is that you connect with your laptop, which will be used as "display" and then you connect with your smart phone and that will be used as "joystick". The entire setup works very well.

Now that it all works, I decided to refactor the code. I realized that the relationship between the joystick and the display is one way (the display never needs to send information back to the joystick). Therefore I decided that I did not need any signalR invokable client functions on the joystick (e.g. there is no use for gameHub.client.joyStickMethod() in the joystick js.

It was then I discovered something strange

It turns out that hub method public override Task OnConnected() that I override to deal with the different types of clients (displays and joysticks) is not invoked unless I define a myHub.client.clientSideMethod(). Here's the example I'm dealing with:

        var gameHub = $.connection.gameHub;
        gameHub.client.connection();
        $("#joystick").joystick({
            hub: gameHub
        });

        gameHub.client.activateJoystick = function () { };
        $.connection.hub.qs = "type=joystick&gameId=" + "@Model.Id";
        $.connection.hub.start();   //this will invoke on connected

You see that empty client side method? That's the reason why OnConnected is called on server side. If I remove that line of code, it will not be called.

        var gameHub = $.connection.gameHub;
        gameHub.client.connection();
        $("#joystick").joystick({
            hub: gameHub 
        });

        //gameHub.client.activateJoystick = function () { };
        $.connection.hub.qs = "type=joystick&gameId=" + "@Model.Id";
        $.connection.hub.start();   //this will invoke on connected

This will not work, since there is no client side method on the Hub. I can probably add a RegistrateJoystickmethod on the Hub and call that, but I think that the behavior is unexpected. My question is therefore:

Is there a way to manually "connect" to the hub, so that the OnConnect method will be called?

Share Improve this question edited Jan 11, 2013 at 8:10 pardahlman asked Jan 11, 2013 at 7:58 pardahlmanpardahlman 1,45411 silver badges22 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 14

That's by design. If you don't have any subscriptions to the hub then that particular client can't won't get any messages from server to client. You can still invoke methods on the hub.

A way around this is to just have a fake Hub that you wire up to. Does nothing, returns void. At least this way, when you bootstrap your game, before you call .start() on the connection, you wire up to this fake method on the fake hub. This will get you the onConnected() method.

I agree, this is such odd behaviour. If you make a connection, onConnected() should be raised, even if you're not listening to events.

What makes this even more odd is if you're doing Hub authorization. If you derive from the AuthorizeAttribute, in your case, the AuthorizeHubMethodInvokation() will be called for each method you call on the client, but the AuthorizeHubConnection() will never be called.

--Update

I played around with this on my project. I had the iniital idea of creating a hub proxy on the client that doesn't exist on the server, but this fails. However, you can just hook up to a real hub but a fake callback. This does work and lets you get away with creating a real method.

This is clearly a horrible work around, but in the face of nothing else, does the job.

As pardahlman says, we need to register an event before OnConnected and OnDisconnected work.

connection = $.hubConnection("http://localhost:9002");

var proxy = connection.createHubProxy("testHub");

//without this on listener, OnConnected and OnDisconnected doesn't raise.
proxy.on("messageToClients", (message) => {

});

await connection.start(function () {
    console.log("Connected");
})

Microsoft documentation mention it, but is very difficult to fine that note.

发布评论

评论列表(0)

  1. 暂无评论