Does anybody have an example of what to do in the OnStart method of a windows service to start the connection and keep it open. There are many examples of doing this in a console app, but not a windows service. The following code does not work, as my client
can not find it. But if I use this code in a Console app it works?
using (WebApplication.Start("http://localhost:8080")
When you write a windows service doesn't it just keep running by default? In a console application the application will quit unless you keep it open and that's why the Console.ReadLine is needed.
I did manage to solve this issue. The below is the code from the service. You have to assign the WebApplication.Start to a property in the service so that it retains it. If you don't do this, it will lose the reference when the "OnStart" method completes.
I am aslo including the snipit of code that will send out the message from the Timer using a specific Hub.
public IDisposable WebAppStart { get; set; }
protected override void OnStart(string[] args)
{
tmrMain.Interval = 5000
WebAppStart = WebApplication.Start<StartUp>("http://localhost:8080");
tmrMain.Start();
}
private void tmrMain_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// Send to Students Hub
var context = GlobalHost.ConnectionManager.GetHubContext<Students>();
// Send is the method exposed in the Hub
// StudentList is the object it will send
context.Clients.All.Send(StudentList);
}
Marked as answer by tsmccartan on Jan 30, 2013 07:40 PM
public class MessageHub : Hub
{
private TraceSwitch _traceSwitch = new TraceSwitch("HTTP Stream Trace", "HTTP Stream Trace");
public MessageHub()
: base()
{
System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "MessageHub() instance instantiated.");
}
public void Configuration(IAppBuilder app)
{
System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Mapping the SignalR hubs now.");
HubConfiguration config = new HubConfiguration();
//app.MapHubs();
app.MapHubs();
System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR hubs all mapped.");
}
public override Task OnReconnected()
{
System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR connection reconnected to MessageHub.");
return base.OnReconnected();
}
public override Task OnDisconnected()
{
System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR connection disconnected from MessageHub.");
return base.OnDisconnected();
}
public override Task OnConnected()
{
//BroadcastMessage();
Task baseTask = base.OnConnected();
System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR connection received and connected.");
return baseTask;
}
public void Send(string message)
{
}
}
But when I start the Windows service, although the SignalR jQuery attempts to connect to my Windows service, the OnConnected() event of the MessageHub class won't fire.
The MessageHub class is instantiated though; the trace in the default constructor runs.
This is the code in the client that connects to the server and will accept posts from the Windows Service.
</head>
<body>
<script src="Scripts/json2.min.js"></script>
<script src="Scripts/jquery-1.8.3.min.js"></script>
<script src="Scripts/jquery.signalR-1.0.0-rc1.min.js"></script>
<script>
jqSR = jQuery.noConflict(true);
</script>
<script>
jqSR(function () {
// Open a connection to the remote server
var connection = jqSR.hubConnection('http://localhost:8080');
// Connect to the Hub
var students = connection.createHubProxy('Students');
// Connect to the Send method of the Hub
students.on('Send', function (message) {
makeListView2(message);
// Turn logging on so we can see the calls in the browser console
connection.logging = true;
// Start the connection
connection.start().done(function () {
alert("Now connected!");
}).fail(function () {
alert("Could not Connect!");
});
});
function makeListView2(jObject) {
// Do Work with the object
}
})
</script>
<ul id="news">
</ul>
<div id="divNewStudent">
<span id="spanStudentList"></span>
</div>
</body>
</html>
I think I got it working because I turned on the System.Net tracing and saw HTTP messages exchanged between the web page and server. However I got this error thrown in my log files:
HttpStreamer.exe Error: 0 : SignalR exception thrown by Task: System.AggregateException: One or more errors occurred. ---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: T. Path '', line 0, position 0. at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonTextReader.ReadInternal() at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader) at Newtonsoft.Json.Linq.JObject.Parse(String json) at Microsoft.AspNet.SignalR.Hubs.HubRequestParser.Parse(String
data) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) at Microsoft.AspNet.SignalR.PersistentConnection.<>c__DisplayClassa.<>c__DisplayClassc.<ProcessRequest>b__7() at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass3c.<FromMethod>b__3b()
at Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod[TResult](Func`1 func) --- End of inner exception stack trace --- ---> (Inner Exception #0) Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: T. Path '', line
0, position 0. at Newtonsoft.Json.JsonTextReader.ParseValue() at Newtonsoft.Json.JsonTextReader.ReadInternal() at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader) at Newtonsoft.Json.Linq.JObject.Parse(String
json) at Microsoft.AspNet.SignalR.Hubs.HubRequestParser.Parse(String data) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) at Microsoft.AspNet.SignalR.PersistentConnection.<>c__DisplayClassa.<>c__DisplayClassc.<ProcessRequest>b__7()
at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass3c.<FromMethod>b__3b() at Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod[TResult](Func`1 func)<---
What does this above exception mean? It seems to indicate the string sent to the server is a badly formatted JSON object but I am only sending plain text right now...
I don't know if I can help with that, as I have not seen that error. Maybe use IE9 Developer tools, turn on Network Monitoring and look at the response that is being sent to the browser?
tsmccartan
0 Points
4 Posts
SignalR Hosted in Windows Service
Jan 26, 2013 06:50 PM|LINK
Does anybody have an example of what to do in the OnStart method of a windows service to start the connection and keep it open. There are many examples of doing this in a console app, but not a windows service. The following code does not work, as my client can not find it. But if I use this code in a Console app it works?
using (WebApplication.Start("http://localhost:8080")
{
Console.WriteLine("Server running");
Console.ReadLine();
}
davidfowl
Contributor
2699 Points
611 Posts
Microsoft
Re: SignalR Hosted in Windows Service
Jan 28, 2013 04:56 AM|LINK
How do you normally keep windows services running? This really isn't a SignalR specific question.
Senior SDE, ASP.NET Team, Microsoft
derricklau
Member
22 Points
29 Posts
Re: SignalR Hosted in Windows Service
Jan 30, 2013 07:19 PM|LINK
I have the same question too.
Don't understand the question:
If you could give more details regarding your question that would help alot.
davidfowl
Contributor
2699 Points
611 Posts
Microsoft
Re: SignalR Hosted in Windows Service
Jan 30, 2013 07:30 PM|LINK
When you write a windows service doesn't it just keep running by default? In a console application the application will quit unless you keep it open and that's why the Console.ReadLine is needed.
Senior SDE, ASP.NET Team, Microsoft
tsmccartan
0 Points
4 Posts
Re: SignalR Hosted in Windows Service
Jan 30, 2013 07:40 PM|LINK
I did manage to solve this issue. The below is the code from the service. You have to assign the WebApplication.Start to a property in the service so that it retains it. If you don't do this, it will lose the reference when the "OnStart" method completes. I am aslo including the snipit of code that will send out the message from the Timer using a specific Hub.
public IDisposable WebAppStart { get; set; } protected override void OnStart(string[] args) { tmrMain.Interval = 5000 WebAppStart = WebApplication.Start<StartUp>("http://localhost:8080"); tmrMain.Start(); } private void tmrMain_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // Send to Students Hub var context = GlobalHost.ConnectionManager.GetHubContext<Students>(); // Send is the method exposed in the Hub // StudentList is the object it will send context.Clients.All.Send(StudentList); }derricklau
Member
22 Points
29 Posts
Re: SignalR Hosted in Windows Service
Jan 31, 2013 04:34 PM|LINK
Thanks! What did you put in your Startup class?
Mine looks like this:
public class MessageHub : Hub { private TraceSwitch _traceSwitch = new TraceSwitch("HTTP Stream Trace", "HTTP Stream Trace"); public MessageHub() : base() { System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "MessageHub() instance instantiated."); } public void Configuration(IAppBuilder app) { System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Mapping the SignalR hubs now."); HubConfiguration config = new HubConfiguration(); //app.MapHubs(); app.MapHubs(); System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR hubs all mapped."); } public override Task OnReconnected() { System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR connection reconnected to MessageHub."); return base.OnReconnected(); } public override Task OnDisconnected() { System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR connection disconnected from MessageHub."); return base.OnDisconnected(); } public override Task OnConnected() { //BroadcastMessage(); Task baseTask = base.OnConnected(); System.Diagnostics.Trace.WriteLineIf(_traceSwitch.TraceVerbose, "SignalR connection received and connected."); return baseTask; } public void Send(string message) { } }But when I start the Windows service, although the SignalR jQuery attempts to connect to my Windows service, the OnConnected() event of the MessageHub class won't fire.
The MessageHub class is instantiated though; the trace in the default constructor runs.
tsmccartan
0 Points
4 Posts
Re: SignalR Hosted in Windows Service
Jan 31, 2013 04:46 PM|LINK
The below is my Hub.
public class Students : Hub { public void Send(List<CarPoolObjects.Student> message) { try { Clients.All.send(message); } catch (Exception ex) { System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog(); appLog.Source = "CarPoolApp"; appLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error); } } public override Task OnConnected() { try { return Clients.All.joined(Context.ConnectionId, DateTime.Now.ToString()); } catch (Exception ex) { System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog(); appLog.Source = "CarPoolApp"; appLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error); } return null; } public override Task OnDisconnected() { try { return Clients.All.leave(Context.ConnectionId, DateTime.Now.ToString()); } catch (Exception ex) { System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog(); appLog.Source = "CarPoolApp"; appLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error); } return null; } public override Task OnReconnected() { try { return Clients.All.rejoined(Context.ConnectionId, DateTime.Now.ToString()); } catch (Exception ex) { System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog(); appLog.Source = "CarPoolApp"; appLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error); } return null; } }</head> <body> <script src="Scripts/json2.min.js"></script> <script src="Scripts/jquery-1.8.3.min.js"></script> <script src="Scripts/jquery.signalR-1.0.0-rc1.min.js"></script> <script> jqSR = jQuery.noConflict(true); </script> <script> jqSR(function () { // Open a connection to the remote server var connection = jqSR.hubConnection('http://localhost:8080'); // Connect to the Hub var students = connection.createHubProxy('Students'); // Connect to the Send method of the Hub students.on('Send', function (message) { makeListView2(message); // Turn logging on so we can see the calls in the browser console connection.logging = true; // Start the connection connection.start().done(function () { alert("Now connected!"); }).fail(function () { alert("Could not Connect!"); }); }); function makeListView2(jObject) { // Do Work with the object } }) </script> <ul id="news"> </ul> <div id="divNewStudent"> <span id="spanStudentList"></span> </div> </body> </html>derricklau
Member
22 Points
29 Posts
Re: SignalR Hosted in Windows Service
Jan 31, 2013 05:35 PM|LINK
Thanks.
What's the code for your Startup class?
derricklau
Member
22 Points
29 Posts
Re: SignalR Hosted in Windows Service
Jan 31, 2013 07:05 PM|LINK
I think I got it working because I turned on the System.Net tracing and saw HTTP messages exchanged between the web page and server. However I got this error thrown in my log files:
HttpStreamer.exe Error: 0 : SignalR exception thrown by Task: System.AggregateException: One or more errors occurred. ---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: T. Path '', line 0, position 0. at Newtonsoft.Json.JsonTextReader.ParseValue() at Newtonsoft.Json.JsonTextReader.ReadInternal() at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader) at Newtonsoft.Json.Linq.JObject.Parse(String json) at Microsoft.AspNet.SignalR.Hubs.HubRequestParser.Parse(String data) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) at Microsoft.AspNet.SignalR.PersistentConnection.<>c__DisplayClassa.<>c__DisplayClassc.<ProcessRequest>b__7() at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass3c.<FromMethod>b__3b() at Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod[TResult](Func`1 func) --- End of inner exception stack trace --- ---> (Inner Exception #0) Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: T. Path '', line 0, position 0. at Newtonsoft.Json.JsonTextReader.ParseValue() at Newtonsoft.Json.JsonTextReader.ReadInternal() at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader) at Newtonsoft.Json.Linq.JObject.Parse(String json) at Microsoft.AspNet.SignalR.Hubs.HubRequestParser.Parse(String data) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) at Microsoft.AspNet.SignalR.PersistentConnection.<>c__DisplayClassa.<>c__DisplayClassc.<ProcessRequest>b__7() at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass3c.<FromMethod>b__3b() at Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod[TResult](Func`1 func)<---
ProcessId=9588 ThreadId=4 DateTime=2013-01-31T19:56:50.0729184Z
What does this above exception mean? It seems to indicate the string sent to the server is a badly formatted JSON object but I am only sending plain text right now...
tsmccartan
0 Points
4 Posts
Re: SignalR Hosted in Windows Service
Jan 31, 2013 08:51 PM|LINK
I don't know if I can help with that, as I have not seen that error. Maybe use IE9 Developer tools, turn on Network Monitoring and look at the response that is being sent to the browser?