I want to inspect certain WCF messages not all.
We have some methods with a specific return type. e.g. :
MyApplication.Entities.SpecificResponse
I know I can clone the messasge, dig into the soap message, but it looks to be expensive to inspect for all messages.
Related
As I have been able to verify, in MassTransit with Azure Service Bus, each type of object consumed by a "Consumer" generates a Topic for that type regardless of whether it is only consumed in a specific "receive endpoint" (queue). When sending a message of this type with the "Send()" method, the message is sent directly to the "receive endpoint" (queue) without going through the topic. If this same message is published with the "Publish()" method, it is published in the Topic, and is forwarded to the receive endpoint (queue) from the corresponding subscriber.
My application uses a CQRS pattern where the messages are divided into commands and events. Commands use the send-receive pattern and are therefore always dispatched in MassTransit with the "Send()" method. The events, however, are based on the publish-subscribe pattern, and therefore are always dispatched in MassTransit with the "Publish()" method. As a result, a large number of topics are created on the bus that are never used (one for each type of command), since the messages belonging to these topics are sent directly to the receiver's queue.
For all these reasons, the question I ask is whether it is possible to configure MassTransit so that it does not automatically create the topics of some types of messages consumed because they will only be sent using the "Send()" method? Does this make sense in MassTransit or is it not possible/recommended?
Thank you!
Regards
Edited 16/04/2021
After doing some testing, I edit this topic to clarify that the intention is to configure MassTransit so that it does not automatically create the topics of some types of messages consumed, all of them received on the same receive endpoint. That is, the intention is to configure (dynamically if possible, through the type of object) which types of messages consumed create a topic and which do not in the same receive endpoint. Let's imagine that we have a receive endpoint (a queue) associated with a service, and this service is capable of consuming both commands and events, since the commands are only dispatched through Send(), it is not necessary to create the topic for them, however the events that are dispatched via Publish(), they need their topic (and their subscribers) to exist in order to deliver the message and be consumed.
Thanks in advance
Yes, for a receive endpoint hosting a consumer that will only receive Sent messages, you can specify ConfigureConsumeTopology = false for that receive endpoint. You can do that via a ConsumerDefinition, or when configuring the receive endpoint directly.
UPDATE
It is also possible to disable topology configuration per message type using an attribute on the message contract:
[ConfigureConsumeTopology(false)]
public interface SomeCommand
{
}
This will prevent the topic/exchange from being created and bound to the receive endpoint.
While I can understand the desire to be "pure to the CQRS mantra" and only Send commands, I'd suggest you read this answer and take it into consideration before overburdening your developers with knowing every single endpoint in the system by name...
For some reason, all the examples I find on WCF MSMQ show void as the return type of the method. Is this just coincidence? If not, why? What are the valid return types?
There are no valid Return types for sending to to a WCF service on an MSMQ end point.
Because you are writing to a queue and not directly communicating with the service the communication channel is not available for the service to send a response. Additionally one of the major benefits of writing to the queue is that the service may not even be running at the point the message is sent, the message will get picked up once the service becomes active again.
If no exception is thrown whilst sending to the service then you know that the message has at the very least been added to the message queue.
In wcf when i send to method which is one way-
I don't need to get answer now...
later,I need to get an answer for sure.
But how can I be sure that he got the message (to deal with it later )?
What about the 202 reponse ?
http://thejoyofcode.com/One_Way_operations_in_services.aspx
I think the article that you linked to does a nice job explaining it:
a one-way service call doesn't wait for the call to be processed, only
to be delivered - where delivery includes deserialization of the
request.
If you don’t get an exception then the message was successfully acknowledged as received.
IsOneWay introduces asynchronous aspects to your API. If you choose to go that route and you want to know what happened after the message was received, you’ll have to build that mechanism yourself. At a high level there’s nothing WCF specific about the solution. Either:
Call the service back and ask what the result was –OR–
Have the service call you back when its done
I have a self hosted WCF 4.0 service with an HTTPS endpoint. I have method that writes some trace info after the message comes in. However, some messages are 400k in size, so there is a long wait conceivably between when WCF has it and my console app has it. How can I get a hook or interception layer in there so I can at least know when a message is first coming in?
I think there is a WCF Performance Counter related to this, so there must be some way to know...
Thanks for all ideas!
This is not the same as Detect WCF client open channel operation , this is about knowing when the HTTP traffic first comes in. Maybe its not that I need to monitor things on my WCF service, maybe I need to monitor some other WCF layer that is intercepting HTTP. Can anyone say?
What about making a custom MessageEncoder that simply wraps the default implementation, but overrides ReadMessage() and logs some information before calling the wrapped implementation (which creates a Message instance)? At this stage the full message isn't even fully streamed over the wire, hence it's a very early point of the processing pipeline. Obviously, however, you don't know anything about the message yet. But if you want to get a timestamp, that might be a convenient place to get it.
One option is implement the IDispatchMessageInspector interface for your service with your message size checking code in the AfterReceiveRequest method override. Your code should look something like the code in this blog post.
I'm contemplating a project where I'll be required to make use of what is variously called the "asynchronous" mode, or the "duplex" mode, or the "callback" mode of SOAP webservice. In this mode, the caller of the service provides in the SOAP header a "reply-to" address, and the service, instead of returning the output of the call in the HTTP response, creates a separate HTTP connection to this "reply-to" address and posts the response message to it. This is normally achieved in WCF using a CompositeDuplexBinding, like so:
<binding name="async_http_text">
<compositeDuplex clientBaseAddress="http://192.168.10.123:1234/async" />
<oneWay />
<textMessageEncoding messageVersion="Soap12WSAddressing10" />
<httpTransport useDefaultWebProxy="false" />
</binding>
This results in not one, but two HTTP connections per call: one from the client to the service, and then one from the service back to the client. From the point of view of the service implementation, nothing changes, you have a method that implements the interface method, and you take in the request and return the response. Fantastic, this is what I need, almost.
In my situation, the request and response can be separated by anything from minutes to days. I need a way to decouple the request and the response, and "store" the state (message, response URI, whatever) until I have enough information to respond at a later time (or even never, under certain circumstances).
I'm not terribly excited about having my methods essentially "paused" for up to days at a time, along with the required silly timeout values (if they're even accepted as valid), but I don't know how to go about putting a system like this together.
In order to be completely clear, I'm implementing a set of standards provided by a standards body, so I do not have flexibility to change SOAP message semantics or alter protocol implementations. This sort of interaction is exactly what was intended when the ReplyTo header was implemented in WS-Addressing.
How would you do it? Perhaps Workflow Foundation enables this sort of thing?
In such case don't use HTTP duplex communication as defined in WCF. It will simply not work because it is dependent on some other prerequisities - session, service instance living on the server, etc. It all adds a lot of problems with timeouts.
What you need is bi-directional communication based on fact that service exposes one way service and client exposes one way service as well (services can be two-way to support some kind of delivery notification). You will pass client's address in the first request as well as some correlation Id to differ multiple requests passed from the same client. You will call client service when the request is completed. Yes, you will have to manage all the stuff by yourselves.
If you are in intranet environment and your clients will be Windows based you can even think about changing your transport protocol to MSMQ because it has built-in support for all these requirements.
Edit:
I checked your updated question and you would call your communication pattern as Soap Messaging. I have never did it with WCF but it should be possible. You need to expose service on both sides of the communication - you can build your service to exactly follow needed contracts. When your service receives call you can use OperationContext.Current.IncommingMessageHeaders to access WS-Addressing information. You can store this information and use them later if you need them. The problem is that these information will not contain what you need. You have to fill them first on the client. This is generally possible by using OperationContextScope and filling OperationContext.Current.OutgoingMessageHeaders. What I'm affraid is that WCF can be "to clever" and override your changes to outgoing WS-Addressing information. I will probably try it myself during weekend.
It turns out the Windows Workflow Foundation (v4) does indeed facilitate this sort of message exchange.
Because WF allows you to decouple the request and response, and do basically whatever you want in the middle, including persist the workflow, idle it, and go outside and cut the grass, you get this capability "for free". Information can be found at these URLs:
Durable Duplex (MSDN)
Workflow 4 Services and duplex communications