B4J Question [SOLVED] Websocket connection to MQTT based API

bdunkleysmith

Active Member
Licensed User
Longtime User
I am trying to connect to a data streaming API and below is an extract from the API documentation (in red italics).

Connection to the message broker is made using a Websocket connection and the message broker makes use of the MQTT protocol.

So my initial obstacle is that I understand that jMQTT does not support a websocket connection used by the API and so I am wondering if there is a workaround.

I have successfully made the separate authorization call which returned a number of things required to make the connection:
  • An endpoint parameter
    This is an authorized url where you make a websocket connection to the message broker.
  • A client identifier
    This is the identifier you must use when connection to the message broker.
  • A list of topics
    For each permission scope you requested you will receive a topic that you can subscribe/publish to.
It provides some example Python code using the paho.mqtt.client library, but as I'm not Python literate, it means little to me:

Python:
urlparts = urlparse(connection_url)
host = urlparts.netloc
client = Client(client_id=client_id, transport="websockets")
client.tls_set()
headers = {'host': host, 'Host': host}
client.ws_set_options(
    path="{}?{}".format(urlparts.path, urlparts.query),
    headers=headers
)
client.on_connect = _on_connect
client.on_message = _on_message
client.connect(host, 443, 15)
client.loop_start()

def _on_connect(client, userdata, flags, connection_result):
    print("connected")

def _on_message(client, userdata, msg):
print("received message {}".format(msg))

Any suggestions on how I can use B4J to access this API would be greatly appreciated, but I fear this project may have hit a roadblock which I'll be unable to overcome.

Thanks,

Bryon
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0
Solution

bdunkleysmith

Active Member
Licensed User
Longtime User
I have not been able to connect to the MQTT broker referred to in post #1 using websocket and suspect this is due to the "authorized url where you make a websocket connection to the message broker" returned by the authorisation call containing a query string.

Format of the "authorised url" (with line feeds added to make the query parameters more visible) is:

wss://xxxxxxxxxxxxxxxxxx.amazonaws.com/mqtt?
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=xxxxxxxxxxxxxxxxxxxxxx&
X-Amz-Date=20210429T234727Z&
X-Amz-Expires=86400&
X-Amz-SignedHeaders=host&
X-Amz-Signature=xxxxxxxxxxxxxxxxxxxxxxxxx&
X-Amz-Security-Token=xxxxxxxxxxxxxxxxxxxxxxxxxxx%3D%3D

Should I be able to use the "authorised url" as is? If not, do I need to separate out the url components, given the example Python code (above) includes the urlparse function to do that as I understand it and then somehow use them with Connect2 or another method?
 
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
includePort is an optional parameter in the authorisation call of the API I wish to access, with the documentation saying "If true, the returned signed WebSocket endpoint URL will include the port (default: false). Some websocket/mqtt libraries require this."

Indeed my connection required inclusion of the port in the URL and so I am very pleased with the update by @Erel of jMQTT to allow websockets.
 
Upvote 0
Top