Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR Cannot invoke a non-delegate type

Tags:

signalr

I'm trying to learn SignalR by writing a really simple application... it basically sends "Hello" periodically (like the Stock Ticker, but a lot simpler).

Here's my hub:

public class StockTickerHub : Hub
{
    public void Hello()
    {
        var s = StockTicker.stockTicker;

        Clients.All.hello();
    }
}

...and here's the code that is supposed to periodically send the messages:

public class StockTicker
{
    public static StockTicker stockTicker = new StockTicker();
    private Thread thread;

    public StockTicker()
    {
        var stockTickerHub = GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>();

        this.thread = new Thread(() =>
            {
                while (true)
                {
                    stockTickerHub.Clients.All().hello();
                    Thread.Sleep(1000);
                }
            }
        );

        this.thread.Start();
    }
}

I'm getting a RuntimeBinderException at stockTickerHub.Clients.All().hello();. It says:

An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll

Additional information: Cannot invoke a non-delegate type

What am I doing wrong?

Client-side JavaScript is below, just in case you need to replicate this.

<script type="text/javascript">
    $(function () {
        
        var chat = $.connection.stockTickerHub;

        chat.client.hello = function () {
            $("#log").append("Hello");
        }

        $.connection.hub.start().done(function () {

            chat.server.hello();
        });
    });
</script>
like image 339
Gigi Avatar asked Dec 03 '22 16:12

Gigi


1 Answers

Simply change:

stockTickerHub.Clients.All().hello();

to:

stockTickerHub.Clients.All.hello();

The debugger should have already tell you this error. I tried your code after the update. It is working.

A remark on the code design:

I wouldn't start a new sending thread in the hello event, that would start one every time this method is invoked by any client. I don't think that's what you want to do. As a smoother example you could start the ticker in Startup class. (If you want a ticker per connection override OnConnected, get the client's connection id and give them separate tickers...)

like image 56
DDan Avatar answered Feb 12 '23 07:02

DDan