Logging from Service to a client - c#

I have a .NET service with a WCF host that uses Nlog for logging. I also have a WPF client that acts as a WCF client for the .NET service. The .NET services logs all message to a file (for now).
I want to use the client to output the current logged messages (ie, if a logging occurs while the client is open, then it'll be showed in a textbox for instance). If the client is closed, I don't need to see the messages.
I've thought of several ideas, but I'm not sure how good they are:
I could set up another host on the client that can receives messages from the Service.
MSMQ (with or without WCF), but then I think it'll just keep adding messages, which I don't want.
I could just open the Logfile itself, but I don't know which one will be the active logfile (seeing as this is handled by Nlog)
Are there any other ideas? Is there a better way for such communication between a (Windows) service and a client?

You might want to look into SignalR. Here's an example that does something like what you are after to display WF tracking records in a browser: http://blog.petegoo.com/2011/10/02/workflow-service-tracking-viewer/.

Related

Add TCP logger to existing windows service without rebuilding

I have a windows service running in a production environment that I need to perform some diagnostic work on. The service listens on a specified port, receives and processes a TCP request, and issues a TCP response.
What I'd like to do is intercept this request and response so I can log it to a database. However I cannot recompile the code and need to make as few changes to the server as possible.
I seem to recall a past instance where a colleague was able to create an interceptor DLL and drop this into the root folder of a WCF or Web API service in order to accomplish a similar task. Would it be possible to accomplish something like that with this TCP service?
As long as the app uses System.Net.Socket, you can use the built in .net network tracing via app.config, docs from Microsoft here.
Adding source System.Net.Socket and System.Net with maxdatasize 1024 will cause it to log the first 1024 bytes of each send and receive.

How to configure WCF log tracing through separate components?

There are several XmlWriterTraceListener-s for each WCF server component.
When user do some action logs are written in different e2e files according to each component. Now we can roundly associate records through separate log files by time-stamp. But it doesn't guarantee accuracy.
The example when such logging is needed:
Some function is evaluating on server and writing logs. We want to know from which client this request was come. Because several clients may work at one time.
May be we should link calls from different components for somehow?
E.g. use something like "token" or "guid" for each callback from client and then bind events from different logs by it?
Is there maybe any standard option for configuring WCF logs?
Yes, there is. This is called activity tracing and WCF supports propagating activities. See more here: Configuring Tracing
As far as I understand your client sends multiple requests to different WCF services in your server. In this case you need client to generate activity ID, then set it as current (use Correlation Manager class) and configure your bindings to propagate activities (see link above).

how to use netMsmqbinding - with server connected scenario

This might look a question where you can read the answer on MSDN, but I still want to ask about the scenario, as I want to solve the business problem.
I have a service hosted on a server, and a client makes service calls. It currently uses netTCP binding. Everything works fine when the service is available, when the server is up and running. Now, I need to handle the server down scenario. I use the local cache file on the client to serve the client requests in case of server down scenario. Now I want to cache all the requests made while server down and want to make service calls once server is up and running.
I am thinking about using the netMsmqBinding, because all I've read suggests that it works well in the disconnected scenario.
Q.1 Can I use the netMsmq to handle this scenario?
Q.2 If not then what could be another approach with which I can follow to solve this problem?
Q.3 Can I use WS-Discovery in case of server down to find that the client calls won't be able to contact the service?
EDIT : The scenario is Client-Server. But i do need to give response on every call to the client. The client is also developed and maintained by me only so i am in a good position to implement the best suitable solution.
Please guide me as I'm not too good with WCF.
Yes, you can use netMsmqBinding for this purpose. We are doing that for services running over a satellite link that can be down often.
One important limitation you need to take into account is that all calls must be one way, being a queue-based transport. If you need to get the results of a request, you'll have to provide a separate response mechanism (it can be a similar queue in the opposite direction)
Ad question 1: using MSMQ is excellent for a scenario where the service may not always be up and running. Note that the server that hosts the message queue must be up and reachable to receive the messages. However, you haven't told us anything else about your scenario, particularly why you currently have NetTCP. The reason that's important, is because there are some things you can not do with MSMQ, for example duplex communication won't work out of the box.
Ad question 2: an alternative may be to implement logic in the client (it's unclear from the question if you're the owner of the client software) to have a local queue and retry messages later if a service is (temporarily) offline. I guess you may even have a proxy MSMQ service on the client, relaying the messages to the main service once it's up.
Ad question 3: yes, you can use Discovery for this. The service will have to announce to the clients when it goes online or offline. The simplest example is using the UdpAnnouncementEndpoint. In the clients you can use the AnnouncementService class to listen to the service coming online or offline, and keep a local list of available services. Alternatively (for example when UDP broadcasts aren't feasible) you can create a discovery proxy service at a well known location that listens to announcements, which the clients can access for instant-knowledge on whether the service they need is online

How to implement TCP/IP responder "service" in web application

I have the following architecture for a project I'm working on.
My question is how to begin implementing the TCP/IP responder part.
It's function, in case the diagram is hard to read, is to wait for a connection from the Order Viewing client, and subsequently notify said client of incoming orders.
I was thinking a queue, but unfortunately I don't know where something like this would fit in the VS2008 hierarchy of things.
If it's part of the ASP.NET web page, should I use the application start event to start the TCP IP responder?
It's not a web service, because those respond to http requests...
If I had to implement your "TCP responder" I'd probably implement it as a windows service and have both the ASP.NET app and the Winform client contact it (e.g. to avoid the problem of recycling of the ASP.NET etc.)
That said, I can think of gazillion easier ways to get the effect you want to achieve (getting the winform client to know about new orders) such as
Using Queues as you mentioned. Windows comes with MSMQ (you need to enable it in add windows features). Using MSMQ from C# is fairly easy. You can also use WCF if you like
exposing an http endpoint on the client and have the client notify the ASP.NET server where it is listening by calling one of its pages
write the orders to the DB and poll it from the client/use System.Data.SqlClient.SqlDependency to know when there's a change
Heck even writing the orders to a file on a shared folder with a FileSystemWatcher would work (though I'd probably wouldn't recommend that)
Why don't you use http? You already have the http server so you don't need any TCP responder - just do http polling at the client.
And if you don't want polling or have too many clients then you can use something like SignalR for notifications.

How to store WCF sessions so another application can access them

Hi I have an application that operations like this..
Client <----> Server <----> Monitor Web Site
WCF is used for the communication and each client has its own session on the server. This is so callbacks can be used from the server to callback to the client.
The objective is that a user on the "Monitor Website" can do the following:
a) Look at all of the users currently online - that is using the client application.
b) Select a client and then perform an action on the client.
This is a training system so the idea being the instructor using a web terminal can select his or her target client and then make the client application do something. Or maybe they want to send a message to the client that will be displayed on the clients screen.
What I cant seem to do is to store a list of all the clients in the server application, that can then be retrieved by the server. If I could do this I could then access the callback object for the client and call the appropriate method.
A method on the monitoring website would look something like this...
Service.SendMessage(userhashcode, message)
The service would then somehow look up the callback that matches the hashcode and then do something like this
callback.SendMessage(message)
So far I have tried without look to serialise the callbacks into a centralised DB. However, it doesnt seem possible on the service to serialise a remote object as the callback exists from the client.
Additionally I thought I could create a global hash table in my service but im not sure on how to do this and to make it accesible application wide.
Any help would be appreciated.
Typically, WCF services are "per-call" only, e.g. each caller gets a fresh instance of the service class, it handles the request, formats the response, send it back and then gets disposed. So typically, you don't have anything "session-like" hanging around in memory.
What you do have is not the service classes themselves, but the service host - the class that acts as the host for your service classes. This is either IIS (in that case you just need to monitor IIS), or then it's a custom app (Windows NT Service, console app) that has a ServiceHost instance up and running.
I am not aware what kind of hooks there might be to connect to and "look inside" the service host - but that's what you're really looking for, I guess.
WCF services can also be configured to be session-ful, and keep a session up and running with a service class - but again: you need to have that turned on explicitly. Even then, I'm not really sure if you have many API hooks to get "inside" the service host and have a look around the current sesssions.
Question is: do you really need to? WCF exposes a gazillion of performance counters, so you can monitor and record just about anything that goes on in WCF - wouldn't that be good enough for you?
Right now, WCF services aren't really hosted in a particularly well-designed system - this should become better with the so-called "Dublin" server-addon, which is designed to host WCF services and WF workflows and give admins a great experience monitoring and managing them. "Dublin" is scheduled to be launched shortly after .NET 4.0 becomes available (which Microsoft has promised will be before the end of calendar year 2009).
Marc
What I have done is as follows...
Created a static instance in my service that keeps a dictionary of callbacks keyed by the hashcode of each WCF connection.
When a session is created it publishes itself to a DB table which contains the hash code and additional connection information.
When a user is using the monitor web application, it can get a list of connected clients from the DB and get the hashcode for that client.
If the monitor application user wants to send a command to the client the following happens..
The hashcode for the sessionn is obtained from the db.
A method is called on the service e.g. SendTextMessage(int hashcode, string message).
This method now looks up the callback to the client from the dictionary of callbacks and obtains a reference to it.
The appropriate method in this case SendTextMessage(message) is called on the callback.
Ive tested this and it works ok, Ive also added a functionality to keep the DB table synchronised to the actual WCF sessions and to clean up as required.

Categories