ExcelDNA RTD with SignalR

336 Views Asked by At

I'm trying to hook up ExcelDNA RTD with a ASP.NET SignalR server. Whenever there is a change on the server a message get pushed to the connected clients, and my ExcelDna add-in is getting the new messages but the registered function is not updated.

My RTD server:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
using ExcelDna.Integration;
using ExcelDna.Integration.Rtd;

namespace DMT.Excel.AddIn
{
    [ComVisible(true)]
    public class SignalRServer : ExcelRtdServer
    {
        private HubConnection _connection;
        private List<Topic> _topics = new List<Topic>();

        public TradesRtdServer()
        {
            _connection = new HubConnectionBuilder()
                .WithUrl("http://localhost:5000/api/test/hub")
                .WithAutomaticReconnect()
                .Build();

            _connection.On<object>("Test", m =>
            {
                foreach (Topic topic in _topics)
                {
                    topic.UpdateValue(m);
                }
            });


            Task.Run(() => _connection.StartAsync());
        }

        protected override bool ServerStart()
        {
            DmtAddIn.Logger.Information("ServerStart");
            return true;
        }

        protected override void ServerTerminate()
        {
            DmtAddIn.Logger.Information("ServerTerminate");
        }

        protected override object ConnectData(Topic topic, IList<string> topicInfo, ref bool newValues)
        {
            DmtAddIn.Logger.Information("ConnectData: {0} - {{{1}}}", topic.TopicId, string.Join(", ", topicInfo));
            _topics.Add(topic);
            return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA);
        }

        protected override void DisconnectData(Topic topic)
        {
            _topics.Remove(topic);
            DmtAddIn.Logger.Information("DisconnectData: {0}", topic.TopicId);
        }
    }
}

My function


        [ExcelFunction(Name = "SignalR.Test.RTD")]
        public static object GetSignalRMessages()
        {
            return XlCall.RTD("Excel.AddIn.Trading.SignalRServer", null, "Test");
        }

When I debug I can see topic.UpdateValue(m); is being hit whenever a message is pushed from the server but not GetSignalRMessages

Am I missing anything to propagate the topic change to the function?

Thank you!

Joseph

2

There are 2 best solutions below

1
jo31 On

I managed to solve this by sending a string from the SignalR server, then deserialize it on the client side

0
Govert On

The ExcelRtdServer checks whether the value passed into UpdateValue is different to the previous value. You might be passing either the same value every time, or some value that is interpreted to an Excel data type as the same (e.g. some object type that is converted to the same string every time).

You might be better off building this through the IObservable or Rx abstractions, that are a bit higher-level than the ExcelRtdServer. See the samples here https://github.com/Excel-DNA/Samples/tree/master/RtdClocks

Maybe something like this project which combines Rx and SignalR: https://github.com/jwooley/SignalrRxSamples