ServiceHost message receive event? - c#

Surely there must be an event to attach onto before a ServiceHost or Channel or Dispatcher handles a message? I'm assuming it can be accessed through OperationContext.Current, but the closest events I can find are Opening and Closing. Is there something like a MessageReceived or BeforeMessageProcessed event?
If not using events, is there some other way using WCF classes/configuration to determine if a ServiceHost SingletonInstance is currently processing a DataContract?
EDIT: IDispatchMessageInspector (AfterReceiveRequest and BeforeSendReply) is perfect. I have about 8 services and need to know what messages (DataContracts) they are currently processing. While it would be possible to use something like a helper method that takes a delegate and does BeforeReceive(); InvokeDelegate(); AfterReceive(); it's far easier to use IDispatchMessageInspector and behaviors.

As far as I know, there isn't such an event at the service host level directly. Could you explain what you're trying to accomplish?
Normally, if you've got any processing that must be done whenever a message arrives, then the right way is to use one of the several extensibility points that WCF offers for this, like IDispatchMessageInspector. In this case, you'd inject your message inspector into the WCF pipeline through a service or an endpoint behavior.

Related

Condition when subscribers in NServiceBus send an auto-subscribe message

I am finding out that even when my NSB process does not handle messages for say DTOXXX, it is still sending an auto-subscribe message to the publisher queue for DTOXXX.
This is not the desired behavior. I want the process to publish and subscribe to messages for DTOYYY, but any communication using DTOXXX is strictly send only.
If that wasn't clear enough I have 2 assemblies that contains my DTO. I Want to establish a pub/sub bus, but only for assemblies in YYY.dll. As for the DTOs in the other assembly, I want the communication to be done via SEND only (not pub sub).
The problem I am running across is that NSB is sending auto subscribe message to the other process even though:
There is no handler for the DTOs in the XXX assembly. It's being referenced only so that YYY NSB can send messages to XXX NSB.
The communication between the 2 modules are strictly SEND only. This is done to promote low coupling given the actual use case & biz requirement.
How can I set up my modules properly? That is I need to somehow tell NSB, to auto subscribe for messages but only for the ones in a given namespace/assembly.
You can define your own rules for which messages are considered commands/events (or plain messages) by implementing your own DefiningEventsAs in the configure interface. Nsb will only autosubscribe to events. That may help you for your usecase...
There are a couple of ways to handle this, the first being that you can turn of auto-subscribe and subscribe manually. This is done via .DoNotAutoSubscribe() in you endpoint config. From there you will resolve and instance of IBus and then subscribe explicitly to the messages you care about.
The second way is to separate your messages from all other code into different assemblies and only map the events(pub/sub) to the Publisher via the app.config file.

How best to handle an unexpected socket error?

I have a chat client class
class ChatClient
{
Task ConnectAsync(string server);
Task SendMessageAsync(string message);
Task DisconnectAsync();
}
Once the user has connected with ConnectAsync they are able to call SendMessageAsync to send messages to other users.
Under the hood there is a Connection class which is a very basic wrapper for the Socket class. One of the main differences is that it has an OnError event.
I'm also using an observable message stream (reactive extensions) which reads from the connection and produces a stream of incoming commands from the server.
My question is this - when the socket produces an error, from where am I best to handle this error from? Should I handle it inside the OnError event handler, or should I intercept the error from the observable stream and handle it there?
I can't see any upside or downside either way, so I'm wondering what best practice dictates?
Something about having an event on a connection class has always struck me as being a little hacky, but I don't know why.
Any suggestions? Thanks
I would have to say that the best solution is which ever is most transparent to the end user. If the error affects the user in some way they should be notified or be given the choice of how to proceed. If it is not possible to notify the user then handle the error in a way that allows for easy future improvements.

CommunicationState listener?

Does anyone know of a way to create a listener for a proxy so that when the CommunicationState has changed I can invoke an action or a method?
An example, I want to update my WCF service for a code change. Since the application is in its early development code changes are very frequent. However, instead of annoying my employees with an email tell them that hey they need to restart their application. I would rather avoid them having to restart the app and having to send them an email. I would rather write a listener that looks at the communication state of a service and if it has changed to a faulted stated then attempt to reconnect.
Edit
Maybe some more context here.
InstanceContext context = new InstanceContext(this);
Subscriber = new SubscriptionService.MySubscriptionServiceClient(context);
Subscriber.Subscribe("");
So basically I want to know when the subscription service has stopped so that I can attempt to reconnect every 60 seconds or so. I tried looking for an event in the Subscriber service but I didn't see anything. Would I need to implement something on the service end?
Thanks
You can use the Faulted event available on the InnerChannel property of your generated client class. The State property of the client class is just a wrapper for InnerChannel.State, so this should work as you desire.
(For reference, you can also use the similarly named event on ChannelFactory<TChannel> if you are creating communication channels in code rather than using generated proxies.)

Trigger event from ChannelFactory

We are using the ChannelFactory to connect to our WCF Service. When ever I do a call to the service, I want the Channel factory to trigger another event. Something like 'OnFunctionCall'. How can I add such a event handler to the ChannelFactory. I'm kinda rushed for time, so I hope someone could help.
Working with C#, .net 3.5 SP1
Kind Regards
One possible solution is to create an endpoint behavior and attach it to the factory endpoint (see below). That behavior would add an inspector to the channels the factory creates (which can be either an IClientMessageInspector or an IParameterInspector), and your inspector would trigger the OnFunctionCall event whenever a message is sent to the server.
var factory = new ChannelFactory<IService>(...);
factory.Endpoint.Behaviors.Add(new MyInspector());
For more information on message inspectors you can look at http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx, and for parameter inspectors you can look at http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/26/wcf-extensibility-iparameterinspector.aspx.

delegates across different machines

it seems like it should be dead easy, but i couldn't find anything in google on it:
I have a video store server, and it has multiple client applications, installed on users' machines, communicating via (let's say) web services.
When a DVD is returned, I'd like to be able to notify useres that have been waiting for that DVD.
When dealing with a single application, then that's no problem using delegates.
my question is- can this approach work with remote clients as well?
You can use a duplex WCF service for that.
But if it really is a DVD handling service where the user doesn't need to be notified immediately, I would recommend a solution where the users' clients poll the server every say 10 minutes. It is far more simple to implement.
Yes - you can use .NET remoting. See this article for a simple example:
http://www.codeproject.com/KB/IP/remotingandevents.aspx
If you want to have a client application that will provide a delegate that people can wire up to, then yes. You would use .net remoting for that.
I used this example: http://www.codeproject.com/KB/dotnet/DotNetRemotingEventsExpl.aspx
Basically what you are going to do, is to expose a remoting server that publishes a known object. The trick with events, is that the server has to know about the type that the client is wiring the event handlers to. So what you do in that case is that you also provide an abstract class as an event sink.
Basically that class will look something like this:
public abstract class MyEventSinkClass : MarshalByRefObject
{
public abstract void MyAbstractEventHandler(string arg1, string arg2);
public void MyEventHandler(string arg1, string arg2)
{
MyAbstractEventHandler(arg1,arg2);
}
}
Then on the client side they would create a class, and inherit from MyEventSinkClass. They put their logic for handling the event in the override for MyAbstractEventHandler. When they wire up the instance that they are using remoting for, instead of wiring like you normally would, they need to wire to their instance of the class that inherits MyEventSinkClass to the MyEventHandler Method. Then when the event fires, it will eventually call into the overriden method and execute their code.
You can find the details of how to setup a remoting server and client in the link I gave, it isn't difficult.
If you don't want to invent the wheel, Use a Message Queuing tool.
Then, when a dvd is return you post a message on some queue. The users are registering to the queues of the DVDs they are interesting in.
Then the communication is persistent and async. the users are getting notifications even if they are offline (they'll get it once they connect and poll the queue)

Categories

Resources