How to know the socket being used in JMS? - jms

I used client and the client will create a connection to server via HornetQ and Netty
Each of 1 minute, server will send heart beat and client (who subscribered) will be received this message. In the message, I included the root IP of server
Everything will be OK if this server had only 1 network card (NIC).
But in the case, server have 2 or more network cards. I met issue.
In the message is received by client, the IP of server not right.
I used InetAddress.getLocalHost().getHostAddress() to get to root IP and I known it wrong in this case server had 2 NICs
So can you give me some advise, how I can get right IP here?
Some guys said we can refer "the socket being used for getting right IP". Do you know how we can get it?

First of all I don't understand why you need IP address, If you think of implementing heartbeat, its not required, If you have used org.hornetq.jms.client.HornetQJMSConnectionFactory It automatically does heartbeat check. And If you have two servers and want to differentiate between servers, use a clientId and send it in message header and while listening you can select message based on the clientId or other approach use sync jms calls.

Related

How to implement UDP Hole Punching?

So I am trying to create a p2p file sharing application in Golang. I am running a globally accessible server for the purpose of sharing IP addresses of 2 clients. When both the clients have each other's IP addresses, they can use hole punching to share the files.
But I am facing some problems in the hole punching part. When I send a request to server, the server is going to store the address of the client and it will later relay this address to other client. Problem is that the address being stored on the server is different than the address that is being is used for Hole punching. Suppose that address being stored on server is NATrouterIP1:PORT-A for first client and NATrouterIP2:PORT-B for the second. But when I am using the first client to send a message to second client, it shows that the message was sent from NATRouterIP1:PORT-C. PORT-A generally stays around 65000. But this PORT-C is 1024. For my application to work these ports should be same. Can someone explain what the issue is?
Github: https://github.com/killtheverse/go-send

Requests from server to client

I know already about the web-sockets, and they are great, the problem with them is that they have to keep the connection open in order to be able to communicate.
I have a small system where from time to time the server has to update the status and notify the clients about that, and keeping the connection open from every client is not so optimal. At same time is very important that the update on the client side to be made just in time.
So my question is, if the server has a unique address does the client have a public temporary address where the server can send request? So when the client will connect to the server it will provide it's unique address and the server will cache it, and when there will be an update the server will send the request to that address?
I understand that there many problems as the address will constantly change, but this is already other question.
If client does not have a dedicated IP-address then it is not available from WAN unless it has an open connection with any node in it.
When client from local network sends request to a server it's (client's) router remembers client's local IP-address and port and translates it using NAT protocol to one of router's free ports and then sends data further with router's own 'IP-address of the sender' in IP protocol header and 'Sender's port' in TCP header. When router get's server's response it uses NAT table from it's memory to translate addresses back and deliver data to the client. Addresses are normally kept in NAT table while connection between server and client is open. So if there are no opened connections between server and local network client then server will not be able to connect with client because server does not know how to reach it.
You say you have a small system. Why then do you think that you will not have enough free ports at your server to work with websockets? If you just want to get updates from the server (not to both send and get data through a persistently opened connection) you'll probably find long polling or SSE more suitable. It is definitely easier to implement than websockets.

Using ZeroMQ to send replies to specific clients and queue if client disconnects

I'm new to ZeroMQ and trying to figure out a design issue. My scenario is that I have one or more clients sending requests to a single server. The server will process the requests, do some stuff, and send a reply to the client. There are two conditions:
The replies must go to the clients that sent the request.
If the client disconnects, the server should queue messages for a period of time so that if the client reconnects, it can receive the messages it missed.
I am having a difficult time figuring out the simplest way to implement this.
Things I've tried:
PUB/SUB - I could tag replies with topics to ensure only the subscribers that sent their request (with their topic as their identifier) would receive the correct reply. This takes care of the routing issue, but since the publisher is unaware of the subscribers, it knows nothing about clients that disconnect.
PUSH/PULL - Seems to be able to handle the message queuing issue, but looks like it won't support my plan of having messages sent to specific clients (based on their ID, for example).
ROUTER/DEALER - Design seemed like the solution to both, but all of the examples seem pretty complex.
My thinking right now is continuing with PUB/SUB, try to implement some sort of heartbeat on the client end (allowing the server to detect the client's presence), and when the client no longer sends a heartbeat, it will stop sending messages tagged with its topic. But that seems sub-optimal and would also involve another socket.
Are there any ideas or suggestions on any other ways I might go about implementing this? Any info would be greatly appreciated. I'm working in Python but any language is fine.
To prepare the best proposition for your solution, more data about your application requirements. I have made a little research about your conditions and connnect it with my experience about ZMQ, here I present two possibilities:
1) PUSH/PULL pattern in two direction, bigger impact on scalability, but messages from server will be cached.
Server has one PULL socket to register each client and get all messages from clients. Each message should have client ID to for server knowledge where send response.
For each client - server create PUSH socket to send responses. Socket configuration was sent in register message. You can use also REQ/REP pattern for register clients (assign socket number).
Each client has own PULL socket, which configuration was sent to server in register message.
It means that server with three clients required to (example port numbers in []):
server: 1 x PULL[5555] socket, 3 x PUSH[5560,5561,5562] sockets (+ optional 1 X REQ[5556] socket for registrations, but I think it depends how you prepare client identity)
client: 1 x PUSH[5555] socket, 1 x PULL[5560|5561|5562] (one per client) (+ optional 1 X REP[5556])
You have to connect server to multiple client sockets to send responses but if client disconnects, messages will not lost. Client will get their own messages when it reconnect to their PULL socket. The disadvantage is requirements of creating few PUSH sockets on server side (number of clients).
2) PUB/SUB + PUSH/PULL or REQ/REP, static cocket configuration on server side (only 2), but server has to prepare some mechanism for retransmit or cache messages.
Server create PUB socket and PULL or REQ. Client register it identity by PULL or REQ socket. server will publish all messages to client with this identity as filter. Server use monitor() function on PUB socket to count number of connected and disconnected clients (actions: 'accept' and 'disconnect'). After 'disconnect' action server publish message to all clients to register again. For clients which not re-register, server stop publish messages.
Client create SUB socket and PUSH or REQ to register and send requests.
This solution requires maybe some cache on server side. Client could confirm each message after get it from SUB socket. It is more complicated and have to be connected with your requirement. If you just would like to know that client lost message. Client could send timestamps of last message received from server during registration. If you need guarantee that clients get all messages, you need some cache implementation. Maybe other process which subscribe all messages and delete each confirmed by client.
In this solution server with three clients required to (example port numbers in []):
server: 1 x PUB[5555] socket, 1 x REP or PULL[5560] socket + monitoring PUB socket
client: 1 x SUB[5555] socket and own identity for filter, 1 x REQ or PUSH[5560] socket
About monitoring you could read here: https://github.com/JustinTulloss/zeromq.node#monitoring (NodeJS implementation, but Python will be similar)
I think about other patterns, but I am not sure that ROUTER/DEALER or REQ/REP will cover your requirements. You should read more about patterns, because each of it is better for some solutions. Look here:
official ZMQ guide (a lot of examples and pictures)
easy ROUTER/DEALER example: http://blog.scottlogic.com/2015/03/20/ZeroMQ-Quick-Intro.html

NAT router blocking JMS messages

I have an openjms-0-7-7 instance running on my cloud machine. The connection to the jms topic happens over tcp. I run the client application on my personal computer at home and I am able to send messages to the topic (which then get forwarded correctly to other listeners) but I am unable to receive messages. My PC is connected to the internet through a NAT router.
I have tried to reproduce this issue using my university network and it all worked fine (there I am assigned my own external IP address - no NAT).
Am I right thinking that the problem is my router blocking the messages? How can I check this and also, how can I fix this.
Best regards,
Bart
Your router is most probably blocking incoming JMS messages as it does not know to which local client (after NAT) it belongs.
You will have to configure port forwarding in your router. Please refer to its documentation for that. To know which ports to forward, you will have to consult openjms's documentation to see how it assigns ports to clients.

Unsolicited notifications from server to client over http

I am working on a dropbox like system and I am wondering how the client gets notified when the files change on the server side. It is my impression that both dropbox and ubuntu one operate over HTTP ports and work as follows:
1. if files change on client machine, inotify detects it and preforms a push from the client to the server. (I get this part)
2. if files change on the server a simple unsolicited notification (just a message saying "time to sync") is sent from the server to the client. Then the client initiates a sync to the server.
I dont really care which language I do this in. I am just wondering how the client gets contacted. Specifically, what if a client is behind a firewall with its own local IP addresses. How does the server locate it?
Also, what kind of messaging protocols would be used to do something like this? I was planning on doing this over HTTP or SSH, but I have no attachment do that.
I'm not sure what Dropbox is using, but it could be websockets (unlikely, it's a pretty new and not widely deployed thing) or more likely a pending Ajax request from the client to the server -- to which the server only responds when it has new stuff for the client. The latter is the common way to implement (well, OK -- "hack";-) some form of "server push" with HTTP.
It took a little research into networking to see how this would work, but it is far more trivial then I expected. I am now using standard Java sockets for this. Start up the server process which listens for a socket connection. Then start up the client which connects to the server.
Once the connection is made, messages can be sent back and fourth. This works through NAT (network address translation) which is standard method for routing packets on private networks behind a firewall.

Resources