Are Published messages sent to all nodes in a NATS cluster? Or only to nodes with local Subscribers to the message's Subject? - nats.io

Let's say I have a simple 2-server NATS cluster with servers A and B.
If a client on Server A publishes a message to a Subject for which there are no subscribers on Server B, does that message still get sent from Server A to Server B?

Not sure what the goal is here but more details could help clarify the context. If you're asking specifically whether the nodes can pass messages published on another server to a subscribed client, yes.. how long will it stay? Depending on the defined expiration time.. what if the server goes down before it shares with the mesh, almost impossible but can happen.
Also, though you're probably just illustrating, even numbers are not generally advisable in clusters to avoid split-brain situations where it's impossible to locate the truth source (seed server in this case)..

Yes. NATS clustered servers will forward messages that it has received from a client to the immediately adjacent nats-server instances to which it has routes. Messages received from a route will only be distributed to local clients. There is not subscriber checks in the mesh.

It's not a black and white answer because NATS supports many deployment architectures with server to client communications, server to server cluster communications, and cluster to cluster communications through gateways to form super-clusters. Gateways for example optimize the interest graph propagation (i.e. only send data to other clusters if there is interest) Super-cluster with gateways documentation

Related

How XMPP transfer messages between two different servers(of different domains) without any intermediate hops?

My team wants to build a chat app and so we are researching about all the available technologies available at our arsenal. I am concerned about XMPP. So i was reading the Oreilly's "XMPP: The definitive guide", and came across these lines and i quote
In XMPP, messages are delivered as fast as possible over the network. Let’s say that Alice sends a message from her new account on the wonderland.lit server to her sister on the realworld.lit server. Her client effectively “uploads” the message to wonderland.lit by pushing a message stanza over a client-to-server XML stream. The wonderland.lit server then stamps a from address on the stanza and checks the to ad- dress in order to see how the stanza needs to be handled (without performing any deep packet inspection or XML parsing, since that would eat into the delivery time). Seeing that the message stanza is bound for the realworld.lit server, the wonderland.lit server then immediately routes the message to realworld.lit over a server-to-server XML stream (with no intermediate hops).Page 45
Like email, but unlike the Web, XMPP systems involve a great deal of inter-domain connections. However, when you send an XMPP message to one of your contacts at a different domain, your client connects to your “home” server, which then connects directly to your contact’s server without intermediate hops (see Figure 2-4).Page 13
Can anyone please make me understand how can there be no intermediate hops(unlike email).
E-Mail (SMTP) also has no intermediate hops. I assume you confuse the application OSI layer, where XMPP, SMTP and so on live, with the network layer (IP).

Understanding NATS clustering

Section NATS Server Clustering states that:
Note that NATS clustered servers have a forwarding limit of one hop.
This means that each gnatsd instance will only forward messages that
it has received from a client to the immediately adjacent gnatsd
instances to which it has routes. Messages received from a route will
only be distributed to local clients. Therefore a full mesh cluster,
or complete graph, is recommended for NATS to function as intended and
as described throughout the documentation.
Let's assume that I have a NATS cluster of 3 nodes: A -> B -> C ( -> denotes a route). Would you please let me know what will happen wit NATS clients in the following scenario:
A message sent to node A
Node A suddenly terminates before delivering the message to node B
Thanks in advance
In the case you described, the message will be dropped.
Core NATS provides a delivery guarantee of "at most once", so if you cannot tolerate lost messages, your application needs to detect that the message never arrived in its destination and resend the message. You might detect this from a timeout using the request/reply pattern, or implement your own type of remediation for lost messages.
Alternatively, you can use NATS streaming, which provides log based persistence and sits atop NATS. It will guarantee the message will be delivered "at least once".

How is the shortest path in IRC ensured?

RFC 2810 says the following about one-to-one communication:
Communication on a one-to-one basis is usually performed by clients,
since most server-server traffic is not a result of servers talking
only to each other. To provide a means for clients to talk to each
other, it is REQUIRED that all servers be able to send a message in
exactly one direction along the spanning tree in order to reach any
client. Thus the path of a message being delivered is the shortest
path between any two points on the spanning tree.
(Emphasis mine.)
What does this "one direction" mean? To only one client? And how does this "reach any client" and find "the shortest path between any two points [hosts on the IRC network]"?
And why not simply cut the crap and store IP addresses of clients and let IP do its job? After all, IRC is built on top of TCP/IP.
Johannes alludes to the solution but doesn't fully answer your questions. He is however correct in that graph theory is a large part of the answer.
Because each child node in server maps of EFnet and IRCnet have only one parent, the shortest path is the only path between two servers on the graph; the same vertice cannot be visited twice without backtracking. This is called a spanning tree, where all nodes are connected, but no loops exist.
IRC is not necessarily unicast like TCP/IP. It communicates with multiple clients on different servers by broadcasting. The important thing to note is that the Client says 'send 'hi' to everyone on #coding', and the message travels from the client to the connected server. That server passes the message to any connected servers, and those servers pass it on to any clients subscribed to #coding and then on to any connected servers.
There isn't really anything like 'client-to-client' communication; one-to-one is accomplished by sending a message to a user with the specified name; not ip address. NickServs help to prevent people from hijacking names, and temporarily associate a nickname with an IP, refusing to authenticate other IP addresses, and protecting the nickname with a password when authentication expires.
In much the same way as sending a channel message, the user sends a message to the server 'send 'hi' to #nicky', and the server simply passes this message on until the client #nicky is listed as a client connected to the server receiving the message. Bots provide a means for #nicky to receive messages when offline; they sign in under the username.
EDIT: IRC actually opens an invite-only personal channel for client-client communications.
Essentially, the shortest path guarantee is a result of IRCs broadcast policy; the moment a message propagates near the desired user's server, it is forwarded to the desired user. Timestamps presumably prevent echoed messages if there are loops in the graph of servers.
In the architecture section, we find evidence that 'spanning tree' is being used in the proper sense. Servers are aware of eachother so as to prevent loops (guarantee shortest paths) and connect efficiently:
6.1 Scalability
It is widely recognized that this protocol does not scale
sufficiently well when used in a large arena. The main problem comes
from the requirement that all servers know about all other servers,
clients and channels and that information regarding them be updated
as soon as it changes.
and this one below is a result of having no alternate paths/detours to take
6.3 Network Congestion
Another problem related to the scalability and reliability issues, as
well as the spanning tree architecture, is that the protocol and
architecture for IRC are extremely vulnerable to network congestions.
IRC networks are designed to be IP agnostic, and follow the shortest path because messages propagate the whole graph, stopping when they reach an endpoint. Clients and servers have enough information to discard duplicate broadcasts. IRC is a very simple, but effective chatting protocol that makes no assumptions about security, IP, or hardware. You could literally use a networked telegraph machine to connect to IRC.
Every IRC server is connected to one or more servers in the same Network. A client connects to one of the server. Let's suppose we have the following setup:
A
/ \
B C
/ / \
D E F
Let's suppose a client on server A wants to send a message to a user on server E. In that case, server A only sends a message to server C, which will send this message to server E, but not to F.
If a client on A sends a message to a channel with users on the servers B and E then A will send the message to the servers B and C. B will send the message to the users in that channel that are connected to B, C will send the message to server E, which will send the message to it's clients in that channel.
Server D and F will never see the message because nobody in that channel is connected to them, but C will see the message even if nobody in that channel is connected to C because it has to rely the message to E

HTTP proxy server - need to handle dynamic client

I have developed serve-client model based on UDP. Client are connected to server on random basis. I mean number of clients alive at a time is not fixed.
Any new client can communicate any time. It means, there could be 1 live client or 100 clients or any number of clients.
Now in such model, I need to add HTTP requests. Browser could send request to server and then server will forward that to any of client based on some identification.
Is there any method or readymade server(like nginix or lighttpd), which I can use for this requirement.
My big worry is that, destination client are not fixed, they keep changing. Most of server (nginix or lighttd) have static entries for destination address.
I visualize your scenario as multiple sensors that connect to the servers when they have something to say, and then they send a request and wait for the answer.
I visualize you also want to somehow administer such modules so that you want to access to them via HTTP.
You could leave the new configuration items on the regular server so that upon any update connection the response would include (in a piggy-backed fashion) the changes to the node.
Or the server could mark somehow your interest in accessing a certain node, and then, when this connects, the server could notify the interested client. The sensor should pay attention to clients wanting to connect to them during a window time.
Certainly, more information would help us help you.

Game Server: Broadcasting UDP packet over Internet?

A friend of mine made a small LAN-playable game, and ask me to change it, so it could be playable over the Internet. I don't want to make huge changes on the client application.
When a game is created, the server keep sending UDP BROADCAST packets to tell everyone that a game has been created. Now, I just need to change this BROADCAST in order to send these packets to a group of internet IP-adresses.
Can you tell me if the following solution is a good one: I would create a room server, lets call it 'room-broadcast-server', that contains IP adresses of everyone who joined the room. Then, the clients, instead of sending that BROADCAST packet, would send the packet to the room-broadcast-server, which would broadcast this packet to everyone who joined the room.
The problem is: The clients would receive these packets from the 'room-broacast-server' and they would try to comunicate with the room-broadcast-server, instead of comunicating with the machine that created the game. I would like to fool the clients, so that they think the packet came from the game server, and not from the room-broadcast-server. How can I make it?
Are you modifying only the server, or both the server and the clients? I would think that it would be simpler to just remove the broadcasts altogether and have the clients explicitly choose the server they want to connect to, rather than relying on the server broadcasting.
As a version 1, you could simply require players to type in the IP address/DNS name of the server in the client in order to connect.
For version 2, you could add support for a "lobby" where you have a (known) central lobby server that both clients and server connect to in order to find each other (so servers connect to the lobby to announce their presence and then clients connect to the lobby in order to browse servers that they want to connect to).
In a game that I have been writing (but on hold currently due to lack of free time :p) I had written the "lobby" server as a simple PHP+MySQL web application and had the clients and servers use HTTP requests to poll it for updates and so on. That way, I could host the central lobby server on a cheap web host and anybody could host games (the drawback is that cheap web hosts don't allow arbitrary socket connections, so I wasn't able to implement NAT punch-through on it, but if/when the game became popular my plan was to move the lobby server to a more expensive host that did allow arbitrary socket connections...)
Spoofing the source address isn't a suitable mechanism for your normal application protocol. It requires special permissions on client machines, it will be dropped by some networking filters, and is just generally gross and anti-social.
Since you're modifying the clients anyway (to send the messages to the game server instead of to the broadcast address), you can simply have the game server append the "true source" of the packet to each packet it sends out, and have the clients expect and process this information in the packets that they recieve from the game server.
The basic concept (one centric lobby server + multiple game servers) of the 2nd option from Dean is good and very common even in retail online games. One thing I don't understand is why you want to fake IP addresses. Clients should not care what server ip address is as long as it gets valid packets from it. Also, imo, you don't need to create a separate room(?) server since a game server can / should manage a list of clients as clients are connected via a lobby server.

Resources