0

I have a WCF Service which is hosted by a Windows Service. It can also run as a console program when a command argument is present. It has one interface that employs MSMQIntegrationBinding, and another that binds to HTTP for service utility methods. This works well. I have a web application (written for IE 11) that lets the user monitor the service, and perform the utility methods. There are many Console.WriteLines in the code that obviously don't display if the code is running as a service.

My boss has now requested that he be able to view the service in action in a console, like it were running as a console app. I would like to add a new virtual console window to my web app that would just display new Console.WriteLines as they occur on the server. I was thinking I could write a function in my wcf service that would accept the message as a string, do a Console.WriteLine, and then push out the message to any listening clients like my web app console window. I'm thinking of using javascript on the client.

I've read about using Websockets with netHttpBinding for a WCF service and that's the approach I would like to take. However, the examples I see seem to be bi-directional, like chat windows (http://www.codeproject.com/Articles/619343/Using-WebSocket-in-NET-4-5-Part-3) that just echo back a message to the client. I want one way server-to-client messaging. Can somebody help? Here's my latest code try:

IWMLogger.VB

<ServiceContract(CallbackContract:=GetType(IWMLogger_MessageCallback))>
Public Interface IWMLogger_ClientListener
    <OperationContract(IsOneWay:=True)>
    Function ListenForServerMessages() As Task
End Interface

<ServiceContract>
Interface IWMLogger_MessageCallback
    <OperationContract(IsOneWay:=True)>
    Function SendMessageToClient(ByVal msg As String) As Task
End Interface

WMLogger.VB

<ServiceBehavior(InstanceContextMode:=InstanceContextMode.Single)> _
Public Class WMLogger_Service
Implements IWMLogger_Service, IWMLogger_Service_MSMQ, IWMLogger_ClientListener

    Public Async Function ListenForServerMessages() As Task Implements IWMLogger_ClientListener.ListenForServerMessages
        Dim callback = OperationContext.Current.GetCallbackChannel(Of IWMLogger_MessageCallback)()
        If DirectCast(callback, IChannel).State = CommunicationState.Opened Then
            'Not sure what to do here
            'Await callback.SendMessageToClient(
        End If
    End Function
End Class
David P
  • 2,027
  • 3
  • 15
  • 27
  • Added C# as a tag. Hoping to get more attention. I can easily convert c# to vb. Please help! :) – David P Mar 13 '15 at 14:15
  • Each request has only one response? Or there could be many Console.Writeline for each request? – Morcilla de Arroz Mar 17 '15 at 11:57
  • I don't really want there to be a request from the client at all, except maybe an initial RegisterClient. I then want the server to push each individual "Console.WriteLine" to the client. If I have to use long polling then I guess I could have client asynchronously call a GetMessage method, and then whenever a message is returned it would go to the client handler, and then I could make another GetMessage call. However, the preferred method would be like a stock ticker where the Client requests nothing and is just fed new Console.WriteLines as they are generated by the Server. – David P Mar 17 '15 at 13:43
  • If you're doing websockets with .NET and JavaScript, then you probably want to check into using SignalR. – CoderDennis Mar 17 '15 at 21:52
  • [this link](https://msdn.microsoft.com/en-us/library/hh977020%28v=vs.110%29.aspx) shows the way to send multiple callback from the server, [redirect the stdout](http://stackoverflow.com/questions/6024172/is-it-possible-to-intercept-console-output) and then send response. I can not recommend you to use SignalR because my company had a lot of problems with this technology(exceptions, disconnection and etc...) till we decided to remove it. [this stream service](http://www.codemag.com/Article/1210051) look interesting – Old Fox Mar 17 '15 at 23:35
  • EventSource (aka SSE) would solve the push issue, and is much simpler to wireup than websockets if you don't need two-way always-on communication. – dandavis Mar 18 '15 at 23:19
  • dandavis - Would this work on IE11? (Requirement I can't get around) If so, can you show an example? – David P Mar 19 '15 at 12:05
  • The EventSource (SSE) sounds like the least amount of overhead. I would also like to use javascript on the client end to connect. I plan to include Remy's polyfill to support IE. Can somebody please show an example of the WCF code needed, and the javascript code needed. – David P Mar 23 '15 at 14:19

2 Answers2

1

Have you looked into SignalR? Personally I would go this route, having the console app running on your web server register to the same SignalR hub as the clients (i.e. your web app will host the SignalR hub). Then use the console app to push the messages to the SignalR hub on your web app, which will relay them to all listening clients (given the correct setup).

The disadvantage the WCF route has is the usual configuration nightmare, certainly possible - but in my option not as straight forward as SignalR.

Have you seen the following stack overflow question for a good comparison between WCF and SignalR Push data to client using SignalR vs WCF?

There is some great tutorials for this over at http://www.asp.net/signalr

Community
  • 1
  • 1
BMac
  • 2,183
  • 3
  • 22
  • 30
  • I would rather not have to rely on 3rd party application running in the background. Currently I am looking into doing the SSE (as suggested by DanDavis) I really don't need duplex communication in this instance, since the server is doing all the pushing. – David P Mar 23 '15 at 12:08
  • @DavidP SignalR is part of Microsofts core asp.net technology, it isn't really any more 3rd party than the .net framework itself :-). With one line of configuration you can have SignalR do SSE instead of websockets. – BMac Mar 23 '15 at 15:47
  • Ok - if you want the 100 points please show me sample on how to have WCF Service methods send a message through SignalR to javascript client using SSE – David P Mar 23 '15 at 19:06
0

I ended up going with a SignalR solution that finally worked. I think it might be a bit of overkill, but I am just glad it works.

Please see my answer at: WCF SSE via SignalR

Thanks for all the suggestions.

Community
  • 1
  • 1
David P
  • 2,027
  • 3
  • 15
  • 27