using SignalRClient.Contracts; using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using Microsoft.AspNet.SignalR.Client; namespace SignalRClient { [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(IExchangeEvents))] [Guid("3FBA514A-326B-4F34-BFF4-425AF4115B43")] [ProgId("SignalRClient.ExchangeHub")] public class ExchangeHub : IExchangeClient { public const string HUB_DIR = ".\\SignalRClient"; public const string HUB_NAME = nameof(IExchangeHub); public event DoubleEventHandler ExchangeQ; public event DoubleEventHandler ExchangeV; private readonly ICollection disposables; private HubConnection connection; private IHubProxy proxy; public ExchangeHub() { Directory.CreateDirectory(HUB_DIR); this.disposables = new List(); } public bool Connected { get; private set; } public bool Connect(string url) { this.connection = new HubConnection(url); this.connection.Closed += this.Connection_Closed; this.connection.ConnectionSlow += Connection_ConnectionSlow; this.connection.Error += this.Connection_Error; this.connection.Received += this.Connection_Received; this.connection.Reconnected += this.Connection_Reconnected; this.connection.Reconnecting += this.Connection_Reconnecting; this.connection.StateChanged += this.Connection_StateChanged; this.proxy = this.connection.CreateHubProxy(HUB_NAME); var disposableQ = this.proxy.On(nameof(this.SendExchangeQ), x => this.ExchangeQ?.Invoke(x)); var disposableV = this.proxy.On(nameof(this.SendExchangeV), x => this.ExchangeV?.Invoke(x)); this.disposables.Add(disposableQ); this.disposables.Add(disposableV); try { this.connection .Start() .Wait(); } catch (Exception e) { this.FileAppendLine(e.ToString()); } return this.connection.State == ConnectionState.Connected; } public void Dispose() { foreach (var disposable in this.disposables) { disposable?.Dispose(); } this.connection.Stop(); } public void SendExchangeQ(double value) => this.proxy.Invoke(nameof(this.SendExchangeQ), new object[] { value }); public void SendExchangeV(Double value) => this.proxy.Invoke(nameof(this.SendExchangeV), new object[] { value }); private void Connection_Closed() { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine("HubConnection closed!"); } private void Connection_ConnectionSlow() { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine("HubConnection is about to timeout!"); } private void Connection_Error(Exception e) { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine(e.ToString()); } private void Connection_Received(string data) { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine(data); } private void Connection_Reconnected() { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine("HubConnection reconnected!"); } private void Connection_Reconnecting() { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine("HubConnection reconnecting!"); } private void Connection_StateChanged(StateChange state) { this.Connected = this.connection.State == ConnectionState.Connected; this.FileAppendLine($"{state.OldState} -> {state.NewState}"); } private void FileAppendLine(string text) => File.AppendAllText($"{HUB_DIR}\\{DateTime.Now:yyyy_MM_dd}.txt", $"[{DateTime.Now:HH:mm:ss}] {text}{Environment.NewLine}"); } }