jasonrbriggs / stomp.py

“stomp.py” is a Python client library for accessing messaging servers (such as ActiveMQ or RabbitMQ) using the STOMP protocol (versions 1.0, 1.1 and 1.2). It can also be run as a standalone, command-line client for testing.
Apache License 2.0
491 stars 167 forks source link

Issue with connecting with correct stomp #396

Closed tahseenjamal closed 1 year ago

tahseenjamal commented 2 years ago

Install ActiveMQ on ubuntu machine as service Edit /etc/hosts file and use LAN for hostname and 127.0.0.1 for localhost Edit activemq.xml and use hostname instead of 0.0.0.0 Edit jetty.xml and use hostname instead of 127.0.0.1 Restart activemq

Now python stomp won't connect stating cannot connect to 127.0.0.1 even if am giving host as 192.168.1.248, which is my LAN IP

But it still pushed the data to stomp 192.168.1.248

Question is why is it searching for 127.0.0.1 when host is 192.168.1.248

Now more interesting part, I setup ActiveMQ on another machine 192.168.1.12 from that machine I do ssh -R 61613:localhost:61613 tahseen@192.168.1.248 means I tunnelled that remote ActiveMQ to the localhost of 192.168.1.248

Now the stomp program pushes data to remote ActiveMQ even when host is 192.168.1.248

import stomp
import sys
host = sys.argv[1]
message = sys.argv[2]
conn = stomp.Connection([(host,61613)])
conn.connect(wait=True)
conn.send(destination='test', body = message)
conn.disconnect()

Why does the stomp library by default tries to push data to localhost first ?

tahseenjamal commented 2 years ago

And the line causing the issue is in the transport.py in the if statement

not (("127.0.0.1", port) in sorted_host_and_ports

This means if 127.0.0.1 is not there in host, put it :-| Why would you do that ?

tahseenjamal commented 2 years ago

Am sharing information that if there are two actvemq running on the same machine, one which is listening on localhost and another on LAN IP, the current stomp.py library always connects to localhost even if in connection LAN IP is explicitly mentioned

jasonrbriggs commented 1 year ago

The line you quote...

not (("127.0.0.1", port) in sorted_host_and_ports

...only applies if localhost or 127.0.0.1 is included in the list of hosts when creating the connection. i.e. if localhost is in the list of hosts already, then include 127.0.0.1 as well. I can't remember the exact defect that requires that behaviour (this was code likely added a decade ago frankly), but it does not mean that localhost is included by default (it is not). If localhost is included, there is an option (prefer_localhost) which defaults to True, so it picks localhost over any other connection (for perf reasons primarily). As a consequence, I don't recognise this as a valid issue.

tahseenjamal commented 1 year ago

If you don't believe me, run two activemq on a single VM one listening to localhost and other listening to LAN IP of the machine

And then try to connect and produce data to the queue using localhost and then once using LAN IP

You would see that in both the cases it would connect to activemq on localhost and data would be pushed in that. I tested this use case

And what I pointed out, I edited that line in transport.py in my folder and then it corrected

jasonrbriggs commented 1 year ago

I've tried running multiple versions of activemq before. As far as I know you can't (at least not without hacking something). I have tried running activemq on localhost and another instance on another machine, and then tested sending messages to both. It works as expected. A message with localhost as the host goes to the local activemq. A message with the other server name as the host goes to the remote activemq.

tahseenjamal commented 1 year ago

You didn't understand what I said. You don't have to run multiple versions. You use

  1. One activemq binding to localhost
  2. One activemq binding to LAN IP of same machine

Now if you try to connect to the activemq that has binding on LAN IP of machine, your client would still connect to the activemq that has binding with localhost

jasonrbriggs commented 1 year ago

Why not use prefer_localhost=False, try_loopback_connect=False for the constructor then if you want strict control of the connection.