Does MassTransit support MSMQ over HTTP transport? - c#

HTTP transfer has been available since MSMQ 3.0, however I'm afraid MassTransit doesn't offer the feature to use HTTP protocol as transport protocol between queues.
There's a very similar question about this here, which has not been completely answered.
Does anyone know if it's possible for a client to subscribe to a bus and send/receive messages through HTTP? Here's the architecture I'm willing to implement:
I'll have 2 computers in the local network
Computer A runs a server application and MassTransit.RuntimeServices
Computer B runs a client application which sends messages to A
I want the communication between them to be done via http.
I tried to change the address in UseSubscriptionService to http instead of msmq, but it doesn't work. If I set computer's A MSMQ service to Hardened Mode, the client application running on computer B get's a timeout while trying to subscribe to mt_subscriptions.
Bus.Initialize(sbc =>
{
sbc.UseMsmq();
sbc.VerifyMsmqConfiguration();
sbc.UseMulticastSubscriptionClient();
sbc.ReceiveFrom("msmq://localhost/test_queue_client");
sbc.UseSubscriptionService("msmq://m3-dev1/mt_subscriptions"); // maybe I could use http instead of msmq, but it doesn't work
});
Any clues on that??

No, MassTransit does not support HTTP for MSMQ. You could, in theory, add your own transport that supports that. RabbitMQ is a way better transport than MSMQ in every way except if you need to enroll in distributed transactions. And RabbitMQ only requires a single port open between the boxes.

Our approach for distributed integration is to have a custom web service contract with proper security. This defines an input port. The input port actually publishes messages to mass transit buses.
On the other side, the same contract is used to deliver messages to subscribers.
By having a custom contract and http/https transport we are independent on actual message bus in the middle. And this pays of, we were using another bus for like 2 years and 2 years ago we migrated to mass transit based bus without ANY changes to clients (publishers/subscribers).

Related

Using MSMQ without installing MSMQ on client machines

I use WCF to execute some code on a server (takes a long time). The request to execute that code is send from several client machines within the local network (TCP).
Since the code takes a while to execute and there are a bunch of clients, I need to somehow queue the requests.
I thought about using MSMQ as queueing mechanism. As far as I understood, MSMQ has to be installed on the client machines as well, not just the server.
Is it possible to not have to install MSMQ on all clients? Are there any alternatives to MSMQ, or simpler ways to have a queue in between the clients and the WCF-service?
Is it possible to not have to install MSMQ on all clients?
No. You must have msmq installed on all machines which want to participate in the sending and receiving of messages.
Are there any alternatives to MSMQ
Yes, many.
or simpler ways to have a queue in between the clients and the
WCF-service?
WCF uses msmq for queued transport on-premise. However, it is possible to use WCF with Azure Service Bus if you want to run in Azure. Link

How should I design my tcp server program to make `IHostedService`s communicate with each other

I'm re-writing a tcp server program in .net core.
I have difficulties implementing my design.
The server has three basic functions/services:
service 1. accept and manage client connections
service 2. handle each kind of client messages and send acknowledge message
service 3. keep track of inactive clients(clients who haven't sent any message for a time) and close those connections.
I'd like to have each of these functions on a dedicate IHostedService.
But I've no idea how should these services communicate with each other.
These services are registered by AddHostedService, and seem can't be injected.
And I'm not sure if it's a correct way to expose public methods on a Hosted Service for others to call.
The most relevant SO question I've found is this one.
In my situation, it means that I should register one mediator service for each of the three services. It doesn't seem to be a clean way because these mediators are just for communication, without semantic meanings...
I'd like to know if the mediator is the only approach,
or is my design totally incorrect?
That really depends on strategy. Each hosted service could take in a configuration as part of its dependencies for communication. However, TCP port binding will need to be unique.
In a prior life, I wrote a UDP service that broadcast and which TCP services were available for communication and mediated the services in chat room sort of setup. UDP is more of a wide net whereas TCP is specific addressing.
If you were using only TCP, without configuration those services would need to know who is the mediator and what address to reach it at.

Commands between two applications in different networks

I want to send commands from one application (e.g. running on mobile device) to another application (e.g. running on embedded device) which is located in a different network.
I don't want to use VPN or something like port forwarding. So after some research I found some other ways to do that, for example via a cloud messaging service like Azure Service Bus.
Sending commands/messages from the first application to the service bus is not a problem for me. But I don't really understand how two get a connection from the cloud service to the second device? I know I can also send a message from the second device to a cloud service e.g. via HTTPS. And then the cloud service can keep that connection alive. As long as the connection is alive, I can send messages to the second device.
But there are some points I can't understand:
When I have thousands of devices, isn't that a problem to keep thousands of connections alive?
How can the second device listening the connection if there are new messages? Doesn't that needing too much ressources on the embedded device?
I also read about using "long polling" techniques and web sockets. I know too little to understand what are the advantages and disadvantages of those concepts. Which technique should I use for my problem?
To be more platform agnostic, I don't want to use services like Azure IoT Hub.
Edit:
Maybe I can use a web service and implement a MQTT Broker?
I think the mentioned MQTT Broker will get you there, especially as your usecase is exactly what MQTT and it's implementations (brokers and clients) have been built for.
The simplified story is the following:
A MQTT Client running on your Application 'publishes' a MQTT message using a 'topic' (think routing key) to the MQTT broker. A MQTT client running on your Devices have a subscription for the same 'topic' on the broker. This enables the broker to route the message from the application to the devices without the requirement that they know about each others.
As far as I understand your question your concerns are the following:
can all the devices be connected at the same time (thousands of open TCP connections) and therefore receiving messages published from your first application via the broker in 'realtime'.
assuming the devices will disconnect for whatever reasons, e.g. due to network problems or for decreasing energy consumption, how would be ensured that the devices will eventually receive the messages.
how will the devices connect to the broker.
Regarding 1. MQTT brokers are built to handle (and keeping) a massive amount of TCP connections. For example VerneMQ, a MQTT broker I can talk about, as I am one of the core devs, is able to handle over a million connections on one node (with proper server configuration it's actually mainly a matter of available RAM). However we'd only recommend such a setup if the devices are mainly sleeping. Using VerneMQ you can also add more nodes to the cluster and balance the connections among all your cluster nodes.
Regarding 2. A MQTT broker typically implements an offline storage for messages that haven't been send out to a client or haven't been acknowledged by a client. This allows your device to go offline for hours and receive the messages upon reconnect.
Regarding 3. This is specific to your usecase. In the simplest case you configure a fixed IP:Port on every device, and the MQTT client running on the device uses it to connect to the broker. Depending on the ability to reconfigure the devices it makes sense to use DNS lookups, or even to provide a 'backchannel' for reconfiguration.
For standard compliant MQTT client software have a look at Eclipse Paho. For an up-to-date list of available MQTT brokers consult the list of MQTT brokers.

WCF - NetMsmqBinding vs NetTcpBinding

I was going through this article http://weblogs.asp.net/spano/archive/2007/10/02/choosing-the-right-wcf-binding.aspx to choose Binding options.
where i got an unusual doubt of what is mean by
offline or disconnected interaction, choose the NetMsmqBinding
Does that mean the even if service is not running still client using the service ?
Can you share some real time example ?
The 2 bindings are radically different.
NetTcpBinding can be thought of as an MS proprietary format (usually binary) similar in concept to RPC (e.g. can be used to replace .NET Remoting). It is synchronous, i.e. both client and server must be online at the same time, and the client receives a response (almost) immediately.
MSMQ is a Message Oriented Middleware solution by Microsoft, which revolves around asynchronous queues - e.g. if the destination server is offline when the client sends a message, the message will be queued on the client until the server comes back online. Each queue is one way only, although bidirectional communication can be achieved via a second queue back from server to client. Sending WCF MSMQ messages requires that the MSMQ Service be installed on the client. Messages on the queue can have a delivery 'timeout' else will be placed on an applicable dead letter queue.
Real world examples:
I would use NetTcpBinding with binary serialization for high performance, synchronous communication needs between a Microsoft WCF client and server, e.g. uploading files, media etc where Xml would not be useful (otherwise, I would use wsHttpBinding for synchronous Xml / SOAP messaging)
I would use MSMQBinding with DTC enabled to ensure reliable messaging between 2 or more systems (e.g. financial), with at least one of the endpoints being in .Net, and a 'compatable' server (not necessarily WCF, e.g. BizTalk, or other EAI hubs or ESB buses which have adapters for MSMQ, e.g. Bridges exist between MSMQ and MQSeries). Messages would typically be in an Xml format.
TL;DR
Does that mean the even if service is not running still client using the service
Yes. If MSMQ is running locally, the client will get an immediate return successful response (indicating that the message has been queued). This does not however mean that the message has been successfully received by the server.

Data packets from a port to MSMQ

I am new to MSMQ . We have a situation where we have many c# applications(.exe) sending data packets on a port. They can send the data packets to a port . How can I configure MSMQ to automatically read from the port and post these data packets to MSMQ. We cannot afford to loose any of these data packets and so loss of data is not acceptable at all . How can this be done efficiently. Can MSMQ be configured to accept the data packets from port 1801 . If these applications we have wrote to different ports will that be better ? Are if they wrote to one port , how can these messages be sent to the MSMQ directly with NO DATA LOSS.
We want the queue to be transactional. We dont want to use the data packets that arrive.
Please help . Any sample code which can do this task will be of great help.
Please NOTE that the applications are written in C# .NEt. Data loss and slow performance has been a problem and we are trying to solve them using MSMQ. We must see all data packets from these applications in MSMQ.
Thanks
How can I configure MSMQ to automatically read from the port
unless you are prepared to write code I don't think this is possible. So on the assumption that you don't mind a little bit of code for yourself, check out the System.Messaging.Message class. The Body property allows you to send in a byte array.
So provided you are reading from the port into some kind of byte array, putting it into a message should be a doddle.
How can this be done efficiently. Can MSMQ be configured to accept the
data packets from port 1801.
If these applications we have wrote to different ports will that be
better?
1801 is already the default port for MSMQ TCP packets, see MSDN article TCP ports, UDP ports, and RPC ports that are used by Message Queuing.
If your port numbers are indeed important, you may configure the WCF service to listen on certain ports in its address part of the service configuration.
When working with MSMQ you normally do not have to deal with any special ports, except when configuring communication between multiple networks through firewalls (MSDN Article: How To Configure a Firewall for MSMQ Access ).
If possible, I would recommend to stick with the default values.
How can these messages be sent to the MSMQ directly with NO DATA LOSS.
We want the queue to be transactional.
If you use transactional queues you secure the message automatically against data loss. More on this in Queuing in WCF and Reliable Messaging with MSMQ and .NET
Data loss and slow performance has been a problem and we are trying to
solve them using MSMQ. We must see all data packets from these
applications in MSMQ.
MSMQ itself is fast and lightweight, but as with every other tool, it all depends on what you do with it - and how. If you start sending large data packets, MSMQ might get into trouble, too. Keep in mind that MSMQ has some limitations, e.g. for message size.
Here are articles/ tutorials to get you started with WCF in combination with MSMQ:
MSDN: MSMQ and WCF: Getting Started
Message Queuing to Windows Communication Foundation
A more complete scenario with secured communation: Creating a WCF Service with MSMQ Communication and Certificate
Security (Code Project)

Categories