We have a messaging application that uses SignalR on a .NET Framework service to connect to clients of various kinds (native mobile + web in the browser). We're looking at potentially replacing SignalR with RabbitMQ to be able to facilitate communication back and forth between the service and various clients in a full duplex fashion. Would this be a viable usecase for RabbitMQ? In the RabbitMQ tutorials I didn't see a specific example that matched. the RPC example is close but it looks like the client initiates the connection, the server gets it, processes it and sends a reply. The connection is blocking from the server side. Is a usecase possible where both the client and the server are producers as well as consumers and they can asynchronously send/receive messages via the queues that they are subscribed to?
I'm not really sure where to ask this, if it's better asked on a different stack exchange please let me know.
Related
Like the title says.
Is there a way to use gRPC in combination with some kind of message broker/ Queue with .NET?
It does not have to be RabbitMQ. I am open to use alternatives.
\
I want to send messages from 1 client to 2 servers but i need to prevent that the 2 servers process the request at the same time, hence the message queue/broker.
You could do this with Azure Service Bus. Client could be on-premises or in Azure. Same for servers 1 and 2.
Note: You should be able to gRPC to Azure Service Bus, but you may need to use HTTP/REST function for topic/subscription to send messages to Server 1 or 2.
Another approach to consider:
https://grpc.io/blog/grpc-load-balancing/
I think to best answer your question, I assume the reason why you want to use rabbitmq with grpc is because you'd like to have better decoupling from client to servers while still using rpc pattern. With this in mind, this might be something you actually need:
rabbitmq - rpc pattern (could find tutorial from rabbitmq docs)
google protobuf to be your contracts between services
The idea is that client is connected to the queue with two channels, one is to send message where you can specify the destination to be a specific service (in your scenario service1); two is a reply channel where service1 would be sending message back to the client.
Kafka and the confuent platform supports grpc and google proto-buffer as a serialization schema.
I am researching doing a two way communication app, not necessarily peer to peer. Looking at using wcf, I am curious as to the inner workings on all of this. A big concern for me is NAT / firewalling.
I need to have this work without portforwarding on the clients. I will port forward the server, thats fine. but the clients need to be able to connect to the server, and then communicate back and forth through this now open (NAT and Firewall) connection.
The duplex wcf examples I am stydying, all seem to use a client address announced to the server to use for callback. Presuming this is a local lan adress, that wont work for public connections. If its the public address, port forwarding will be needed?
Am I missing something? I want to make a connection, keep it open, and use it in a duplex fashion. Thereby, getting past NAT and firewall restrictions once the client "dials out".
Further more, I am not quite sure on precisely how NAT is implemented. If I "punch" out a connection to a wcf service on port 5555, and receive a reply back, does port 5555 from / to that wcf service address stay in the NAT table? If I were to issue further connections from the server wcf service, and "connect" to a wcf service running on the client, (connect to the client public ip), will the NAT table know its me, and forward the traffic on to the client that initially punched the hole?
My final implementation would be:
Remote client <-> server behind port forward <-> management app issuing commands to the server which relays them to the remote clients.
Am I barking up the wrong tree trying to use wcf? I started working on this using raw tcp a while ago, but picking up the project now again, I would like to go the wcf route to sort out all the overhead on rolling my own raw tcp communication.
Thanks for any insight provided.
EDIT: [PING-PONG] Hello Word?
With duplex services you can have independent communication between a server and clients.
Something to keep in mind about duplex services:
The duplex model does not automatically detect when a service or client closes its channel. So if a service unexpectedly terminates, by default the service will not be notified, or if a client unexpectedly terminates, the service will not be notified. Clients and services can implement their own protocol to notify each other if they so choose.
As far as the NAT/firewall settings preventing your services from working is indeed a good concern to have. However, your situation seems to fall in line with a typical two-way communication setup between client and server. I wouldn't suspect you having trouble getting things to work with a little bit of trial and error.
If I "punch" out a connection to a wcf service on port 5555, and receive a reply back, does port 5555 from / to that wcf service address stay in the NAT table? If I were to issue further connections from the server wcf service, and "connect" to a wcf service running on the client, (connect to the client public ip), will the NAT table know its me, and forward the traffic on to the client that initially punched the hole?
To my knowledge this is basically how NAT works. As long as the public IP of your server is accessible on port 5555 to both inbound/outbound traffic, you should be fine. You should maybe research or ask a question about this on Server Fault.
Am I barking up the wrong tree trying to use wcf? I started working on this using raw tcp a while ago, but picking up the project now again, I would like to go the wcf route to sort out all the overhead on rolling my own raw tcp communication.
I don't think you're barking up the wrong tree. It just depends on what you're trying to accomplish. WCF will do a lot of the heavy lifting for you and let you focus on the core of your application. However, if you're wanting to learn more about socket programming then rolling your own network API/library would be something to continue doing.
WCF duplex performs a callback after a method has run on the server that then runs code on the client.
If i want to execute a method on the client from the server at the push of a button on the server then i don't think WCF duplex is appropriate.
Why would i not just create a client and a server at each end of my 2 applications?
I was one of the people that commented on your previous question so I probably owe you an answer here :o)
You have posted rather a lot of code and I have not looked at it in detail. However, in general terms, there is a reason for using wsDualHttpBinding and duplex contracts in general instead of more of a peer-to-peer approach where you have services on both sides, as follows:
The duplex approach is appropriate where you have a clearly defined server that is running permanently. This provides the hub of the interaction. The idea is that clients are in some way more transient than the server. The clients can start up and shut down or move location and the server does not need to be aware of them in advance. When the client starts up, it is pre-configured to know where the server is, so it can "register" itself with the server.
In contrast, the server does not need to be preconfigured to know where the clients are. It starts up and can run independently of any clients. It just accepts "registrations" from all clients that have valid credentials whenever they come online, and can continue to run after the client goes offline. Also, if the client moves, it just re-registers itself with the server at its new location.
So the server is in some sense a more "important" part of the system. No client can participate in the communication without the server, but the server can operate independently of any client.
To do this with WCF duplex service, you have to do some extra work yourself to implement the publish/subscribe behaviour. Fortunately, the MSFT Patterns and Practises team have provided some guidance on how to do it
http://msdn.microsoft.com/en-us/library/ms752254.aspx
This is fundamentally different from a genuine peer-to-peer approach where there is no well-defined hub (i.e. server) for the network and each node can come and go without affecting the overall functioning of the network.
WCF Duplex is used when you have a Publish/Subscribe setting (also known as the Observer Pattern). Let's say you have a service that subscribes for notifications of some sort (e.g. new email). Normally, you would need to check periodically for updates. Using WCF Duplex, the subscriber can be notified automatically by the publisher when there are updates.
So many programs in the past and even the present operate on a Server/Client basis. Examples include TeamSpeak, Ventrilo, Mumble, etc. These programs typically require going into the router and forwarding ports so that the computer running the server can get the messages from the clients which are sending connection requests to the server's router.
Is there anything in WCF these days that allow you to prevent that sort of thing? I have a chat/file transfer program and I would really prefer that users not have to know how to forward their ports.
What kind of options are there out there in the way of UPnP or Punchthrough? The notion of having to go through and forward all the specific ports that a program uses seems so outdated.
Have a look at WS-Discovery with WCF:
http://weblogs.asp.net/gsusx/archive/2009/02/13/using-ws-discovery-in-wcf-4-0.aspx
The discovery protocol negates a central, "server router" as you put it. It's uses UDP broadcast to notify clients of each other.
Note that the discovery protocol itself is just a stateless messaging protocol. It has no guarantees or state synchronization. If for example, Client A doesn't receive the broadcast message from Client B, then Client A wont know of Client B. The protocol overhead of maintaining this P2P states is complex and usually a single server to hold this state is the easiest approach.
I haven't been able to find a clear answer to this problem. Is there a good way to subscribe to a MSMQ through the internet? Ideally I need security both in authentication and encryption for this connection. But I would like the subscriber to act just like any other client that would be subscribed on the local network. I believe I have a couple of options here
Expose the MSMQ ports publicly
Put the MSMQ behind some type of WCF service (not sure if that works for a subscriber)
What other options do I have? We're sitting in a .NET environment and the main problem domain that is trying to be solved is to change the remote connections from a pulling system to an event based system to reduce the load on the main server.
One way is to use a queue ON the Internet.
I work at Microsoft and my team owns MSMQ and we also own the Windows Azure Service Bus service. For the scenario you describe you may want to take a look at using a Service Bus Queue, which has not only the advantage of being reachable for Internet senders but also eliminates the need to create inbound firewall rules on the receive side.
More here: http://www.windowsazure.com/en-us/develop/net/how-to-guides/service-bus-queues/
The most natural option will be to use MSMQ over http, which is a feature of MSMQ:
http://msdn.microsoft.com/en-us/magazine/cc164041.aspx
The alternative would be to create an http WCF service possibly with duplex polling and use WS-Routing to an MSMQ WCF service.
Checkout the Gateway feature of NServiceBus.