I've been driving myself nuts trying to resolve this issue so really hoping someone has some insight.
I have a console application which runs/hosts my signalR server.
I have already successfully connected to it using a web(javascript) client and a windows forms client with no trouble at all.
BUT for the life of me I cannot get a silverlight client to connect to it. Initially I was getting a
'System.Security.SecurityException' occurred in Microsoft.Threading.Tasks error
on
await Connection.Start();
I managed to fix that by force sending the clientaccesspolicy file using code i found on a random thread.
THREAD
However the connection still never establishes. The status goes thru connecting, disconnected, connection closed.
I am at my wits end as to why this won't work. Any input is appreciated. Code below.
MainPage.xaml.cs
public partial class MainPage : UserControl
{
private SignalRClient client;
public MainPage()
{
InitializeComponent();
dataGrid1.ItemsSource = new ItemsCollection();
client = new SignalRClient();
client.RunAsync();
Debug.WriteLine("Init Done");
}
}
-
SignalRClient.cs
public class SignalRClient
{
private HubConnection Connection { get; set; }
private IHubProxy HubProxy { get; set; }
const string url = "http://localhost:8080/";
public SignalRClient()
{
}
public async void RunAsync()
{
Connection = new HubConnection(url, useDefaultUrl: true);
Connection.Closed += Connection_Closed;
Connection.StateChanged += ConnectionDidSomething;
HubProxy = Connection.CreateHubProxy("TickerHub");
HubProxy.On<string>("receiveAllData", data => Debug.WriteLine("RECDATA={0}", data));
try
{
await Connection.Start();
}
catch (HttpClientException e)
{
Debug.WriteLine("Unable to connect to server.1 {0}", e.Message);
return;
}
catch (HttpRequestException e)
{
Debug.WriteLine("Unable to connect to server.2 {0}", e.Message);
return;
}
}
-
Server
class Program
{
static void Main(string[] args)
{
string url = "http://localhost:8080/";
using (WebApp.Start(url))
{
Console.WriteLine("SignalR server running on {0}", url);
Console.ReadLine();
}
Console.ReadLine();
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
Console.WriteLine("Configuration");
//Tried this approach too
/*app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});*/
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR<ClientAccessPolicyConnection>("/clientaccesspolicy.xml");
}
}
-
TickerHub.cs
public class TickerHub : Hub
{
public override Task OnConnected()
{
string connectionID = Context.ConnectionId;
Console.WriteLine("New Connection:" + connectionID);
InitNewClient(connectionID);
return base.OnConnected();
}
//send all data to newly connected client
public void InitNewClient(string connectionID)
{
}
//client requested all data
public void GetAllData()
{
Console.WriteLine("Get Data Triggered");
Clients.All.receiveAllData("TESTING123");
}
}
I figured it out! Hopefully this helps someone in the future.
Its quite simple. This is what you need to have in your startup class configuration method.
Below that is the code required to send the clientaccesspolicy.xml.
class Startup
{
public void Configuration(IAppBuilder app)
{
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR<ClientAccessPolicyConnection>("/clientaccesspolicy.xml");
}
}
-
public class ClientAccessPolicyConnection : PersistentConnection
{
public override Task ProcessRequest(Microsoft.AspNet.SignalR.Hosting.HostContext context)
{
string[] urlArray = context.Request.Url.ToString().Split('/');
string path = urlArray[urlArray.Length - 1];
if (path.Equals("clientaccesspolicy.xml", StringComparison.InvariantCultureIgnoreCase))
{
//Convert policy to byteArray
var array = Encoding.UTF8.GetBytes(ClientAccessPolicy);
var segment = new ArraySegment<byte>(array);
//Write response
context.Response.ContentType = "text/xml";
context.Response.Write(segment);
//Return empty task to escape from SignalR's default Connection/Transport checks.
return EmptyTask;
}
return EmptyTask;
}
private static readonly Task EmptyTask = MakeTask<object>(null);
public static Task<T> MakeTask<T>(T value)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
public static readonly string ClientAccessPolicy =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<access-policy>"
+ "<cross-domain-access>"
+ "<policy>"
+ "<allow-from http-request-headers=\"*\">"
+ "<domain uri=\"*\"/>"
+ "</allow-from>"
+ "<grant-to>"
+ "<resource path=\"/\" include-subpaths=\"true\"/>"
+ "</grant-to>"
+ "</policy>"
+ "</cross-domain-access>"
+ "</access-policy>";
}
Related
I am new to gRPC and trying to learn it by using the chat server/client sample from cactuaroid here. I’ve modified the code to show progress in a WPF app from a long running task. All code is running on .NET 5 and I’m using the latest versions of the gRPC packages.
The process is working fine when using the computer's IP address but when using computer name for the gRPC client, I’m getting a “DNS resolution failed” exception (computer name is “skylake”):
RpcException: Status(StatusCode="Unavailable", Detail="DNS resolution
failed for service: skylake:6001",
DebugException="Grpc.Core.Internal.CoreErrorDetailException:
{"created":"#1615312867.300000000","description":"Resolver transient
failure","file":"......\src\core\ext\filters\client_channel\client_channel.cc","file_line":2138,"referenced_errors":[{"created":"#1615312867.300000000","description":"DNS
resolution failed for service:
skylake:6001","file":"......\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.cc","file_line":362,"grpc_status":14,"referenced_errors":[{"created":"#1615312867.300000000","description":"C-ares
status is not ARES_SUCCESS qtype=AAAA name=skylake is_balancer=0:
Could not contact DNS
servers","file":"......\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc","file_line":716,"referenced_errors":[{"created":"#1615312866.142000000","description":"C-ares
status is not ARES_SUCCESS qtype=A name=skylake is_balancer=0: Could
not contact DNS
servers","file":"......\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc","file_line":716}]}]}]}")
I verified that I could reach the port with telnet skylake 6001.
I am testing locally, client and server both on the same machine. Oddly enough, the gRPC server seems to be just fine with the computer name. Its just the client that has an issue with it.
Server code:
[Export(typeof(IService))]
public class ProgressServiceGrpcServer : Progress.ProgressBase, IService
{
[Import]
private Logger m_logger = null;
[Import]
private ProgressService m_progressService = null;
private readonly Empty m_empty = new Empty();
private const int Port = 6001;
private readonly Grpc.Core.Server m_server;
public ProgressServiceGrpcServer()
{
m_server = new Grpc.Core.Server
{
Services =
{
Progress.BindService(this)
.Intercept(new IpAddressAuthenticator())
},
Ports =
{
new ServerPort("skylake", Port, ServerCredentials.Insecure)
}
};
}
public void Start()
{
m_server.Start();
m_logger.Info("Started.");
}
public override async Task Subscribe(ChannelName channelName, IServerStreamWriter<ProgressReport> responseStream, ServerCallContext context)
{
context.CancellationToken.Register(() => m_logger.Info($"{context.Host} cancels subscription."));
try
{
await m_progressService.GetProgressReportsAsObservable(channelName)
.ToAsyncEnumerable()
.ForEachAwaitAsync(async (x) => await responseStream.WriteAsync(x), context.CancellationToken)
.ConfigureAwait(false);
}
catch (TaskCanceledException)
{
m_logger.Info($"{context.Host} unsubscribed.");
}
}
public override Task<Empty> Write(ProgressReport request, ServerCallContext context)
{
m_logger.Info($"{context.Host} {request}");
m_progressService.Add(request);
return Task.FromResult(m_empty);
}
}
Client code:
public class ProgressServiceClient
{
private readonly Progress.ProgressClient m_client =
new Progress.ProgressClient(
new Channel("skylake”, 6001, ChannelCredentials.Insecure));
public async Task Write(ProgressReport progressReport)
{
await m_client.WriteAsync(progressReport);
}
public IAsyncEnumerable<ProgressReport> ProgressReports(ChannelName channelName)
{
var call = m_client.Subscribe(channelName);
return call.ResponseStream
.ToAsyncEnumerable()
.Finally(() => call.Dispose());
}
}
Progress write method:
while (inProgress)
{
progressServiceClient.Write(new GrpcServer.ProgressReport
{
Id = Task.Id.ToString(),
PercentDone = percentDone,
TimeRemain = timeRemain
}).Wait();
Thread.Sleep(500);
}
Progress read method:
m_progressService = new ProgressServiceClient();
ChannelName channelName = new ChannelName() { Id = id };
var cts = new CancellationTokenSource();
_ = m_progressService.ProgressReports(channelName)
.ForEachAsync((x) =>
{
Log.Debug($"id: {x.Id} progress: {x.PercentDone}");
}, cts.Token);
this.Dispatcher.Invoke(() =>
{
Application.Current.Exit += (_, __) => cts.Cancel();
this.Unloaded += (_, __) => cts.Cancel();
});
Thanks to #jdweng for pointing me in the right direction, this was solved by adding the DNS suffix to the hostname (skylake.lan in my case).
We can get the DNS suffix via IPInterfaceProperties.DnsSuffix.
Alternatively, (which might be safer) we can use the correct IP address instead of the host name by using something like that.
I'm trying to create a UWP service app on the Raspberry Pi3 which provides the access to the on board UART. I'm facing an issue about the AppConnection Request/response.
this is the service method that handles the incoming requests from client apps
internal class Inbound
{
public static async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
var messageDeferral = args.GetDeferral();
var response = new ValueSet();
bool success = false;
var msg = args.Request.Message.Keys;
if (args.Request.Message.TryGetValue(ServiceApiRequests.Keys.Command, out object command))
{
try
{
switch (command)
{
case ServiceApiRequests.CommandValues.UartWrite:
if (args.Request.Message.TryGetValue(ServiceApiRequests.Keys.UartTxBuffer, out object txBuffer))
{
string rxBuff = "";
success = await Pi3.Peripherals.Uart.GerInstance(57600).Write((string)txBuffer);
if (success)
{
Debug.WriteLine("Tx: " + (string)txBuffer);
if (args.Request.Message.TryGetValue(ServiceApiRequests.Keys.ReadUartResponse, out object getResponse))
{
if ((string)getResponse == ServiceApiRequests.ReadUartResponse.Yes)
{
rxBuff = await Pi3.Peripherals.Uart.GerInstance(57600).Read();
Debug.WriteLine("Rx: " + rxBuff);
}
}
}
response.Add(ServiceApiRequests.Keys.UartRxBuffer, rxBuff);
}
break;
}
}
catch (Exception ex)
{
success = false;
}
}
response.Add(new KeyValuePair<string, object>(ServiceApiRequests.Keys.Result, success ? ServiceApiRequests.ResultValues.Ok : ServiceApiRequests.ResultValues.Ko));
var result = await args.Request.SendResponseAsync(response);
if (result == AppServiceResponseStatus.Failure)
{
Debug.WriteLine("Failed to send the response");
}
messageDeferral.Complete();
}
}
As you can figure out, the Uart class is get using the Singleton pattern using the method Pi3.Peripherals.Uart.GerInstance(57600).
Following the code i using for send the request from the client app.
public static class Uart
{
public static IAsyncOperation<string> SendCommand(this AppServiceConnection DriverControllerConnection, string txBuffer, string awaitResponse = ServiceApiRequests.ReadUartResponse.Yes)
{
return _SendCommand(DriverControllerConnection, txBuffer, awaitResponse).AsAsyncOperation();
}
private static async Task<string> _SendCommand(AppServiceConnection DriverControllerConnection, string txBuffer, string awaitResponse)
{
AppServiceResponse response = null;
string response_str = "";
try
{
if (DriverControllerConnection != null)
{
response = await DriverControllerConnection.SendMessageAsync(new ServiceApiRequests.UartWrite().GetCommand(txBuffer, awaitResponse));
if (response.Status == AppServiceResponseStatus.Success)
{
if (response.Message.TryGetValue(ServiceApiRequests.Keys.Result, out object result))
{
if ((string)result == ServiceApiRequests.ResultValues.Ok && awaitResponse == ServiceApiRequests.ReadUartResponse.Yes)
{
response_str = response.Message[ServiceApiRequests.Keys.UartRxBuffer] as string;
}
}
}
}
}
catch (Exception ex)
{
// TODO: log
}
return response_str;
}
}
The system works well just for a while, until i have response.Status == AppServiceResponseStatus.Success , then the result of the request changes and it becomes AppServiceResponseStatus.Failure. This way the program counter never steps into the condition if (response.Status == AppServiceResponseStatus.Success).
Any idea about the cause?
Thank you so much for the help.
EDIT
Follow the suggestions, i added an handler for the ServiceClosed event. This is the main class.
public sealed class DriverListener : IBackgroundTask
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private AppServiceConnection appServiceConnection;
public void Run(IBackgroundTaskInstance taskInstance)
{
backgroundTaskDeferral = taskInstance.GetDeferral();
// taskInstance.Canceled += OnTaskCanceled;
var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
appServiceConnection = triggerDetails.AppServiceConnection;
appServiceConnection.RequestReceived += Inbound.OnRequestReceived;
appServiceConnection.ServiceClosed += OnTaskCanceled;
}
private void OnTaskCanceled(AppServiceConnection sender, AppServiceClosedEventArgs reason)
{
if (this.backgroundTaskDeferral != null)
{
Debug.WriteLine("ServiceClosed");
// Complete the service deferral.
this.backgroundTaskDeferral.Complete();
}
}
}
Placing a breakpoint in this function, i see that it was never triggered.
The app connection is opened using the singleton pattern, and putted in a dll that i use in the client app
public static AppServiceConnection GetDriverConnectionInstance()
{
if (_DriverConnectionInstance == null)
{
try
{
_DriverConnectionInstance = OpenDriverConnection().AsTask().GetAwaiter().GetResult();
}
catch
{
}
}
return _DriverConnectionInstance;
}
I also add a Request to the service that toggles a led, and i noticed that the led status changes but the response from the app service is still "Failure" and the message is null.
The AppService has a default lifetime of 25sec, unless it is being requested by the foreground experience. When the service shuts down the connection, your client process will receive the ServiceClosed event, so you know you will need to reopen the connection the next time you want to send a request.
I am trying to use web socket with my bot to communicate with the server. But on run time it throws the System.NullReferenceException. I am running socket in background on a different thread so that it does not interfear with the bot.
I am using WebsocketSharp library.
First message comes in just fine but on second message it throws exception at following line in HumanCollaboratorDialog class.
await context.PostAsync(e.Data);
My Socket Stream Class is as following:
public static class SocketStream
{
public static WebSocket ws;
private static List<string> serverMsg = new List<string>();
public static void initializeSocket()
{
ws = new WebSocket("ws://Some IP:8080/human-collaborator/data");
Debug.WriteLine("****** INITIALIZED SOCKET (should happen only once) *****");
Task.Run(() => startSocketStream());
}
private static void startSocketStream()
{
int attempts = 0;
while (!ws.IsAlive)
{
try
{
attempts++;
ws.Connect();
}
catch (WebSocketException)
{
Debug.WriteLine("Connection attempts: " + attempts.ToString());
}
}
ws.OnOpen += (sender, args) =>
{
Debug.WriteLine("# SOCKET OPENED");
};
ws.OnError += (sender, args) =>
{
Debug.WriteLine("# SOME ERROR OCCURED");
};
ws.OnClose += (sender, args) =>
{
Debug.WriteLine("# SOCKET CLOSED");
};
}
}
I am calling the initializeSocket() method in Global.asx to run it on application level
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
SocketStream.initializeSocket();
}
}
My HumanCollaboratorDialog class is as following:
[Serializable]
public class HumanCollaboratorDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(this.MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
SocketStream.ws.OnMessage += async (sender, e) =>
{
try
{
await context.PostAsync(e.Data);
}
catch (HttpRequestException ex)
{
throw ex;
}
};
Thread.Sleep(500);
string output = message.Text;
SocketStream.ws.Send(output);
Thread.Sleep(500);
context.Wait(MessageReceivedAsync);
}
}
My MessagesController has following POST method:
public virtual async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new HumanCollaboratorDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
Neithet e.Data nor context is empty. I think problem is with socket connection or may be i am doing something wrong in SocketStream class. following is the image
Your bot is a web service. Messages are sent to the service by the client (a web page, an application, another service, etc.) and received in the MessagesController's Post method. There's no need to have the socket code on the server for what you're trying to do. Web Sockets are useful for receiving messages on a client from the bot via a Direct Line connection.
Here is an example of using the Bot Framework's Direct Line Client and creating a web socket connection. Notice how the web socket is created from a conversation's StreamUrl:
DirectLineClientCredentials creds = new DirectLineClientCredentials(directLineSecret);
DirectLineClient directLineClient = new DirectLineClient(creds);
Conversation conversation = await directLineClient.Conversations.StartConversationAsync();
using (var webSocketClient = new WebSocket(conversation.StreamUrl))
{
webSocketClient.OnMessage += WebSocketClient_OnMessage;
webSocketClient.Connect();
while (true)
{
string input = Console.ReadLine().Trim();
if (input.ToLower() == "exit")
{
break;
}
else
{
if (input.Length > 0)
{
Activity userMessage = new Activity
{
From = new ChannelAccount(fromUser),
Text = input,
Type = ActivityTypes.Message
};
await directLineClient.Conversations.PostActivityAsync(conversation.ConversationId, userMessage);
}
}
}
}
private static void WebSocketClient_OnMessage(object sender, MessageEventArgs e)
{
// avoid null reference exception when no data received
if (string.IsNullOrWhiteSpace(e.Data))
{
return;
}
var activitySet = JsonConvert.DeserializeObject<ActivitySet>(e.Data);
var activities = from x in activitySet.Activities
where x.From.Id == botId
select x;
foreach (Activity activity in activities)
{
Console.WriteLine(activity.Text);
}
}
This is from a console application that is using the Direct Line to communicate with the Bot and is listening for messages using web sockets here:
https://github.com/Microsoft/BotBuilder-Samples/tree/master/CSharp/core-DirectLineWebSockets
I want to connect to signalr with a client thats on a different pc. This means i wont be using localhost. I already made a simple networkdiscovery to get the correct ip address but it seems signalr does not allow remote clients to connect even though I already use CorsOptions.AllowAll.
class Startup
{
public void Configuration(IAppBuilder app)
{
var hubConfiguration = new HubConfiguration
{
#if DEBUG
EnableDetailedErrors = true
#else
EnableDetailedErrors = false
#endif
};
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(hubConfiguration);
}
}
Iam using duality which is a 2d game engine. Here is the server:
public class SignalRServer : Component, ICmpInitializable
{
private IDisposable _signalRServer;
public int _port { get; set; } = 8080;
public void StopServer()
{
if (_signalRServer != null)
_signalRServer.Dispose();
}
public void OnInit(InitContext context)
{
if (context == InitContext.Activate && DualityApp.ExecContext == DualityApp.ExecutionContext.Game)
{
var networkDiscovery = new NetworkDiscovery(_port, "TestGame"); //Network discovery to get the ip adres of the server if one is found
IPEndPoint ipEndPoint;
if (networkDiscovery.LookForServer(out ipEndPoint))
{
try
{
ConnectToServer(ipEndPoint).Wait();
Debug.WriteLine($"Connection established to {ipEndPoint}");
}
catch (Exception ex)
{
Debug.WriteLine("Could not find server");
}
}
else //No server was found so we create one
{
Debug.WriteLine("Starting signalR server");
string url = $"http://*:{_port}"; //To test go to http://localhost:8080/signalr/hubs
networkDiscovery.Start();
_signalRServer = WebApp.Start<Startup>(url);
}
}
}
private async Task ConnectToServer(IPEndPoint ipEndPoint)
{
var hubConnection = new HubConnection($"http://{ipEndPoint}/");
IHubProxy hubProxy = hubConnection.CreateHubProxy(nameof(MyHub));
hubProxy.On<string, string>(nameof(MyHub.Send), (name, message) =>
{
Debug.WriteLine("Incoming data: {0} {1}", name, message);
});
ServicePointManager.DefaultConnectionLimit = 10;
await hubConnection.Start();
}
public void OnShutdown(ShutdownContext context)
{
StopServer();
}
}
And the hub:
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
public override Task OnConnected()
{
Debug.WriteLine("Client connected: " + Context.ConnectionId);
Send("Server", $"Client with id {Context.ConnectionId} has connected");
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
Debug.WriteLine("Client disconnected: " + Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
}
I have my server console app:
static void Main(string[] args)
{
string url = "http://localhost:8080";
using (WebApp.Start(url))
{
MyHub hub = new MyHub();
Console.WriteLine("Server running on {0}", url);
var key = Console.ReadLine();
while (key != "quit")
{
hub.Send("Server", key);
}
}
}
public class MyHub : Hub
{
public void Send(string name, string message)
{
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.addMessage(name, message);
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
And my .NET client app
static void Main(string[] args)
{
MainAsync().Wait();
Console.ReadLine();
}
static async Task MainAsync()
{
try
{
var hubConnection = new HubConnection("http://localhost:8080/");
//hubConnection.TraceLevel = TraceLevels.All;
//hubConnection.TraceWriter = Console.Out;
IHubProxy hubProxy = hubConnection.CreateHubProxy("MyHub");
hubProxy.On("addMessage", data =>
{
Console.WriteLine("Incoming data: {0} {1}", data.name, data.message);
});
ServicePointManager.DefaultConnectionLimit = 10;
await hubConnection.Start();
}
catch (Exception ex)
{
}
}
I do not get any error when running the client. However, nothing gets printed out on the console.
When I uncomment these 2 lines:
hubConnection.TraceLevel = TraceLevels.All;
hubConnection.TraceWriter = Console.Out;
I am able to see some trace outputs in the console
07:56:28.0121460 - 355ca933-de49-400b-b859-c9dde6361151 - WS: OnMessage({"C":"d-
69A14839-B,0|C,0|D,1|E,0","S":1,"M":[]})
07:56:28.0277722 - 355ca933-de49-400b-b859-c9dde6361151 - ChangeState(Connecting
, Connected)
07:56:33.4655493 - 355ca933-de49-400b-b859-c9dde6361151 - WS: OnMessage({"C":"d-
69A14839-B,1|C,0|D,1|E,0","M":[{"H":"MyHub","M":"addMessage","A":["Server","Hello World"]}]}
)
07:56:37.9657773 - 355ca933-de49-400b-b859-c9dde6361151 - WS: OnMessage({})
07:56:47.9975354 - 355ca933-de49-400b-b859-c9dde6361151 - WS: OnMessage({})
"Server" and "Hello World" are the messages that are being sent from the server, so I guess the client is receiving the messages, just that I'm probably printing them out to the console the wrong way
Can anyone help?
Additional Info: I am able to receive the messages fine on my MVC application.
Shouldn't you declare your hubProxy event handler as this?
hubProxy.On<string, string>("Send", (name, message) =>
{
Console.WriteLine("Incoming data: {0} {1}", name, message);
});