Is it possible to publish message to a specific client id ?
I want to publish two things using mqtt:
1- General informations like users scores, stats etc ... and can be viewable by everyone.
2- Sensitive informations reserved for private user like own score, name etc ...
Is there any clean way to do it using Paho MQTT ?
By the way, using: https://github.com/eclipse/paho.mqtt.golang
No, with the MQTT protocol messages are published to topics, not clients there can be anywhere between 0 and many clients subscribed to a given topic. Also there is no where in the message header to specify the target client id.
All clients subscribed to a topic will receive all messages published to that topic. But clients can subscribe to any number of topics so there is nothing to stop each client subscribing to a topic general topic and one that includes their clientid as an element in the topic. You can then use topic ACLs to ensure that only the client with the matching client id can subscribe to that topic.
Related
I would like to confront my understanding of google pubSub/lite vs RabbitMQ (using MQTT over WSS).
My use case is that I need something like a topic exchange. To send messages individually or to all or to some.
Having RabbitMQ I understand that I can create a topic have multiple queues linked via routingKey. E.g. amqTopic.routingKey1-10.
And I can push a message to a specific queue e.g. like this amqTopic.routingKey8
or push to the entire topic(all queues routed) like this amqTopic.*
Is it possible to create topic exchange structure with Google PubSub and if so how? I am not sure if I miss something. But from what I read I am inclined to say no, because google works like a direct exchange.
Thank you for helping..
This kind of topic exchange structure is possible to re-create using Cloud Pub/Sub filters. You can attach attributes to your messages when they are published (e.g. "routingKey": "8" or "routingKey": "all") and configure filters on your subscriptions to receive only messages meant for a particular routing key (attributes.routingKey="8" OR attributes.routingKey="all" in this scenario).
It's not currently possible to create this kind of topic exchange structure in Pub/Sub Lite.
I need to design a system that allows
Users to subscribe to any topic
No defined topic limit
Control over sending to one device, or all
Recovery when offline clients, (or APNS) that drops a notification. Provide a way to catch up via REST
Discard all updates older than age T.
I studied many different solutions, such as Notification Hubs, Service Bus, Event Hub... and now discovered Kafka and not sure if that's a good fit.
Draft architecture
Use an Event Hub to listen for mobile deviceID registrations, and userIDs that requests for topic subscriptions .. Pass that to Reddis, below
If registering a phone/subscribing to a topic, save the deviceID userID to the topic key.
If sending a message to a topic, query Reddis for the topic key, and send that result to a FIFO queue for processing.
Pipe the output of the previous query into the built in Reddis Pub/Sub features to alert worker roles that there is work pending.
While the workers send notices to Apple and Firebase, archive out the sent notices to some in-memory store below.
Archive server maintains a history of sent events, so that out-of-sync devices can get the most up to date information LIFO-queue style.
Question
What are your thoughts on using this approach to solve the above needs?
What other things should I learn, research, or experiment (measure)?
I use activemq with spring boot.
I wanted send topic only to specific subscribers. I know that to achieve it I can specify selectors on JMSListener but this mean that I already sent message to subscriber. What I want to do is to dispatch messages on broker level.
Currently I have below code:
public Broker broker() throws Exception {
BrokerService broker = new BrokerService();
broker.setBrokerName(BROKER_NAME);
broker.addConnector(BROKER_URL);
policy.setTopic(USER_TOPIC);
broker.start();
return broker.getBroker();
}
Let say I have messages which are able to send two subject BOOKS and FOOD.
For subscriber A only BOOKS are available and for subscriber B BOOKS and FOOD.
Question:
Is it possible to achieve it on broker level? If so how. I know that there is something like destination policy but I don't know how to use it :(
Messages can be routed and secured to different topic or queue destinations in a variety of ways:
Separate topics per subscribers (topic://BOOKS, topic://FOOD)
Single topic, but use a message header (topic://EVENTS)
a. Message header "EVENT_TYPE='FOOD'" or "EVENT_TYPE='BOOKS'"
You can secure the destinations so only the 'books' user can subscribe to the topic://BOOKS and only the 'food' user can subscribe to the topic://FOOD
Use a Virtual Topic which is publish to a topic, subscribe to a queue and get the best of all the above. For example publish to: topic://EVENTS and then subscribe from: queue://vConsumer.BOOKS.EVENTS, queue://vConsumer.FOOD.EVENTS
Links:
ActiveMQ Authorization: http://activemq.apache.org/security.html
ActiveMQ Virtual Topics: http://activemq.apache.org/virtual-destinations.html
Evaluating the MQTT protocol as a chat service to satisfy 1-1, 1-n, n-n communications for clients that may have limited connectivity.
The current design is for every client to by default subscribe to a channel based on their unique id, e.g. 'users/9932947'. Messages (payload: JSON) published to this channel would contain a new randomly generated topic, e.g. 'conversations/2938475', for the conversation to continue.
This would allow for 1-1, 1-n, and n-n communications. And, it would mean the first message sent would start the 'conversation'. New conversations could be started with the same recipient list by initializing a new message. (I'm assuming plugins could handle multiple recipients listed in the
payload, and the logic handling the 1-1,1-n,n-n conversation would
happen client side)
I then face the reality, in pub/sub paradigm, that if user 1234 sends
a message to user 5678, but user 5678 is not subscribed yet, then the
message is lost, which, in some cases, would be bad. Using the
'retain' flag is not ideal, as more than one message may be sent.
So, once a subscriber receives a message, the logic flow would then dictate that the recipient(s) subscribe to the new topic identified in the payload. I'm probably breaking the pub/sub paradigm or maybe I'm missing something when it comes to dynamic topics and message expiration.
Knowing my broker/queue system could consume from my contact database, could persistence sessions be automatically created for users and those user be subscribed to these randomly generated topics/conversations? Is this a bad design? Any issues with scaling?
I have some camel routes with mina sockets and jetty websockets. I am able to broadcast a message to all the clients connected to the websocket but how do i send a message to a specific endpoint. How do i maintain a list of all connected clients with a client id as reference so i can route to a specific client. Is that possible? Will i be able to mention a dynamic client in the to URI?
Or maybe i am thinking about this wrong and i need to create topics on active mq and have the clients subscribe to it. That would mean that i create a topic for every websocket client? and route the message to the right topic.
Am i atleast on the right track here, any examples you can point out? Google was not helpful.
The approach you take depends on how sensitive the client information is. The downside of a single topic with selectors is that anyone can subscribe to the topic without a selector and see all the information for everyone - not usually something that you want to do.
A better scheme is to use a message distribution mechanism (set of Camel routes) that act as an intermediary between the websocket clients and the system producing the messages. This mechanism is responsible for distributing messages from a single destination to client-specitic destinations. I have worked on a couple of banking web front-ends that used a similar scheme.
In order for this to work you first generate for each user a distinct token/UUID; this is presented to the user when the session is established (usually through some sort of profile query/message).
It's essential that the UUID can be worked out as a hash of the clientId rather than being stored in a DB, as it will be used all the time and you want to make sure this is worked out quickly.
The user then uses that information to connect to specific topics that use that UUID as a suffix. For example two users subscribing to an orderConfirmation topic would each subscribe to their own version of that topic:
clientA -> orderConfirmation.71jqsd87162iuhw78162wd7168
clientB -> orderConfirmation.76232hdwe7r23j92irjh291e0d
To keep track of "presence", your clients would need to periodically send a heartbeat message containing their clientId to a well-known topic that your distribution mechanism listens on. Clients should not be able to subscribe to this topic for reads (see ActiveMQ Security). The message distribution mechanism needs to keep in memory a data structure that contains the clientId and the time a heartbeat was last seen.
When a message is received by the distribution mechanism, it checks whether the clientID for which it received the message has a "live/present" session, determines the UUID for the client, and broadcasts the message on the appropriate topic.
Over time this will create a large number of topics on your broker that you don't want hanging around when the user has gone away. You can configure ActiveMQ to delete these if they have been inactive for some time.
You definitely do not want to create separate endpoint for each client.
Topic and a subscription with selector is an elegant way to resolve it.
I would say the best one.
You need single topic, which every client would subscribe to with the selector looking like where clientId in ('${myClientId}', 'EVERYONE'). Now when you want to publish a message to specific client, you set a property clientId to the id of this client. If you want to broadcast, you set it to 'EVERYONE'
I hope I understand the problem right...