I have setup a console application that just runs a loop and emits a message using Signal R. The client that is listening is an angular application.
When I run locally, (Both the Console application and the Angular Site) it works fine. However, when I run my console application in my Vagrant VM (Ubuntu HOST), then I get an all too familiar error message such as the following:
GET http://localhost:12345/signalr/negotiate?clientProtocol=1.5&userId=12345&connectionData=%5B%7B%22
name%22%3A%22testem
itter%22%7D%5D&_=1446565284280 500 (Internal Server Error)
I have ran into issues similar to this before (maybe this exact one) so here are some initial details
The code I have looks like the following:
namespace test
{
public class Program
{
public static void Main(string[] args)
{
try
{
using (WebApp.Start<EmmitStartup>("http://*:12345"))
{
Console.Out.WriteLine("Emmit started on http://*:12345");
IEmitterFactory factory = new EmitterFactory();
while (true)
{
Thread.Sleep(5000);
ITestEmitter emitter = factory.Create((ctx) =>
{
return new TestEmitter(ctx);
});
emitter.SayHello();
emitter.Echo("Hello World:" + DateTime.Now);
}
}
}
catch (Exception e)
{
Console.Out.WriteLine(e.Message);
Console.Out.WriteLine(e.StackTrace);
Console.ReadLine();
}
}
}
public class TestEmitter:Emitter,ITestEmitter
{
public TestEmitter(IEmitterContext emitterContext) : base(emitterContext)
{
}
public TestEmitter(IEmitterContext emitterContext, EmitterModel model) : base(emitterContext, model)
{
}
public TestEmitter(IDictionary<string, object> model) : base(model)
{
}
public void SayHello()
{
EmitterContext.Clients.All.onSayHello();
}
public void Echo(string message)
{
EmitterContext.Clients.All.onEcho(message);
}
}
public interface ITestEmitter
{
void SayHello();
void Echo(string message);
}
public class EmmitStartup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule());
var config = new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true,
EnableJSONP = true
};
map.RunSignalR(config);
});
}
}
}
- There are no exception or error logs being thrown on the server.
- I have enabled CORS in SignalR
- I have tried to use both
http://*:12345
andhttp://localhost:12345
andhttp://0.0.0.0:12345
- The
Emmit
library is just syntactic sugar and makes direct pass through toSignalR
(I have tried same exact with SignalR directly. - I have tried different combinations of enabling/disabling
EnableJSONP
- I know SignalR is working and accessible through the VM because I can hit
http://localhost:12345/signalr/hubs
and it shows proxy file. - I have setup port fowarding to the Vagrant VM for port
12345
- I have disabled firewall on VM HOST (Ubuntu) with
sudo ufw disable
The code for the client looks like the following:
var emmitProxy = null;
Emmit.createProxy({
emitter:'testEmitter',
path:'http://localhost:12345/signalr',
listeners:{
'onSayHello':function(){
$log.info('onSayHello triggered')
},
'onEcho':function(message){
$log.info(message);
}
},
onError:function(){
//an error occured
$log.error('testEmitter:onError');
},
onDisconnected:function(){
//proxy was disconnected
$log.debug('testEmitter:onDisconnected');
},
queryParams:{
userId:'12345' //optional
}
}).then(function(newProxy){
emmitProxy = newProxy;
});
UPDATE
I enabled logging and here is the output. Before another person recommends I enable CORS, I don't think that CORS is the issue, I think its just the cascading impact of something else that is having an issue.
UPDATE
I have ran this in multiple environments with the following results:
- Ran in Docker container on Vagrant VM (Ubuntu) - ERROR OCCURS
- Ran directly on Vagrant VM (Ubuntu) - ERROR OCCURS
- Deployed in Docker Container to Tutum - ERROR OCCURS
- Ran directly through Visual Studio on Windows - EVERYTHING WORKS
- Ran directly on Mac oSX (on Mono obviously) - EVERYTHING WORKS
I have added the following IHubPipelineModule
public class ErrorHandlingPipelineModule:HubPipelineModule
{
public override Func<HubDescriptor, IRequest, bool> BuildAuthorizeConnect (Func<HubDescriptor, IRequest, bool> authorizeConnect)
{
try
{
Console.Out.WriteLine ("BuildAuthorizeConnect");
return base.BuildAuthorizeConnect (authorizeConnect);
}
catch (Exception exception)
{
Console.Out.WriteLine ("AuthorizeConnect Failure");
Console.Out.WriteLine(exception.Message);
}
return base.BuildAuthorizeConnect(authorizeConnect);
}
protected override void OnAfterDisconnect (IHub hub, bool stopCalled)
{
try
{
Console.Out.WriteLine ("OnAfterDisconnect");
base.OnAfterDisconnect (hub, stopCalled);
Console.Out.WriteLine ("After OnAfterDisconnect");
}
catch (Exception exception)
{
Console.Out.WriteLine ("AfterDisconnect Failure");
Console.Out.WriteLine(exception.Message);
}
}
protected override bool OnBeforeDisconnect (IHub hub, bool stopCalled)
{
try
{
Console.Out.WriteLine ("OnBeforeDisconnect");
return base.OnBeforeDisconnect (hub, stopCalled);
}
catch (Exception exception)
{
Console.Out.WriteLine ("BeforeDisconnect Failure");
Console.Out.WriteLine(exception.Message);
}
return base.OnBeforeDisconnect (hub, stopCalled);
}
public override Func<IHub, System.Threading.Tasks.Task> BuildConnect(Func<IHub, System.Threading.Tasks.Task> connect)
{
try
{
Console.Out.WriteLine("BuildConnect");
return base.BuildConnect(connect);
}
catch (Exception exception)
{
Console.Out.WriteLine(exception.Message);
}
return base.BuildConnect(connect);
}
protected override void OnAfterConnect(IHub hub)
{
try
{
Console.Out.WriteLine("OnAfterConnect");
base.OnAfterConnect(hub);
}
catch (Exception exception)
{
Console.Out.WriteLine ("OnAfterConnect Failure");
Console.Out.WriteLine(exception.Message);
}
}
protected override bool OnBeforeConnect(IHub hub)
{
try
{
Console.Out.WriteLine("OnBeforeConnect");
return base.OnBeforeConnect(hub);
}
catch (Exception exception)
{
Console.Out.WriteLine ("OnBeforeConnect Failure");
Console.Out.WriteLine(exception.Message);
}
return base.OnBeforeConnect (hub);
}
}
And when I check my logs, the only logs that are printed out are the following:
BuildConnect
BuildAuthorizeConnect
UPDATE I am not sure if this will be relevant or how I may have missed it, but I checked the response from the 500 and have posted it to Here
It looks like it is showing it is related to Improperly protected user's key pairs in '/root/.config/.mono/keypairs'.
Also, I am not sure if this link contains sensitive information. If somebody can let me know if it does, I would appreciate it.
I did a minimal amount of research thus far and came across SignalR.Owin works under Windows but returns 500 for Mono on Linux
When I check the Network tab for the negotiate request, I get the following
** Headers** Remote Address:127.0.0.1:12345 Request URL:http://localhost:12345/signalr/negotiate?clientProtocol=1.5&userId=12345&connectionData=%5B%7B%22name%22%3A%22testemitter%22%7D%5D&_=1446964166640 Request Method:GET Status Code:500 Internal Server Error
HTTP/1.1 500 Internal Server Error
Access-Control-Allow-Origin: http://localhost:8100
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
Content-Type: text/html
Server: Mono-HTTPAPI/1.0
Date: Sun, 08 Nov 2015 06:30:28 GMT
Connection: close
Transfer-Encoding: chunked
Accept:text/plain, */*; q=0.01
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:JSESSIONID.ae4b31f4=aqpz31hevinaauwftyijure; JSESSIONID.26c95422=1m32u58exuvjz5jrojszqziqh; JSESSIONID.3fd19426=iv9fawaej3nt14yzcruj45si5; JSESSIONID.8868ba42=1gh4w06alx8ehuuj1adr5w8y8; JSESSIONID.947cfb91=nyxfrp6u0pny1sl8gwlouprh4; screenResolution=1280x800
Host:localhost:12345
Origin:http://localhost:8100
Pragma:no-cache
Referer:http://localhost:8100/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36