I'm using XMPP to drive a notification system. Basically I will have a set of services, some of which will broadcast to all users and some which are directed to a specific client (full JID).
For a service that broadcasts to all users a PubSub node seems the obvious choice but for a service that targets its messages to a specific client, I'm unsure of the best mechanism to use.
Do I represent these services as other client users and create bespoke implementations for them? The problem I see with this is how will they be discovered? Do I group them into a chat room and discover that. It feels like a bit of a hack. I could also define my own bespoke type of service, but then I have to define my own XML tags and maintain that.
I know there are plenty of standard extensions to XMPP but I cant see anything useful in this case.
Even in the pubsub case, the publisher (i.e. your service) is still a "user", so this configuration will be pretty standard. We simply create service accounts to represent those "users".
I am unsure of what you mean by "how will they be discovered". Why do the services need to be discovered? Your scenario only gives the use case of services sending messages to the users. Assuming the service already knows who the message is to be sent to, then you don't need any other information to send a message.
Related
What are the best practices for sending system message/s to group/ user, while using XMPP protocol? All the users at at the group should receive the message.
How can I achieve it?
Possible solutions that might be useful:
The announce - I have encountered with the announce and more
specifically this module.
Publish-Subscribe http://www.xmpp.org/extensions/xep-0060.html
There is always the
option of creating an admin user that will send messages.
Thanks in advance.
The best approach depends on your constrain and especially if you control the client. For example, if you use a client you did not develop, it may not render the pubsub messages fine.
The second thing to consider if how are the group defined. Are users registering for alerts ? In that case in seems to match the pubsub case. Otherwise, if groups are not too large, you may use an admin user to send to the list of user you want. You can even send a single message to multiple users using XEP-0033: Extended Stanza Addressing (Sometimes called "multicast").
mod_announce can only target all users or all online users, so it does not seem to match your need in terms of "groups".
I explained most of the option in a talk (video and slides): https://blog.process-one.net/implementing-state-of-the-art-one-to-many-chat-services-with-ejabberd-ejabberd-workshop-1/
It is broader as it not only cover broadcast but also groupchat, but it should help clarifying your choice.
I'm willing to use ejabberd / mongooseIm in a microservice network. XMPP should be our chat protocol aside from a REST API network. I want to send messages incoming at the xmpp server downstream to worker services. Has anybody done this or could lead me into the right direction?
My first thoughts are using RabbitMQ for sending the new incoming messages to the workers.
There are basically two choices to giving your workers access to the messages routed by ejabberd / MongooseIM. I'll focus on MongooseIM, since I know it better (DISCLAIMER: I'm in the dev team).
The first is to scan the message archive in an async / polling fashion. The Message Archive Management describes XMPP level protocol for accessing it, but for your use case the important part is message persistence - so just making sure the relevant module (mod_mam) is enabled in server config and the messages will hit the database. The databases supported for MAM are PostgreSQL and Riak, though there was also some work on a Cassandra backend (YMMV). This doesn't require tinkering with the server / in Erlang for as long as there's a DB driver for your language of choice available. Since PR#657 it's possible to store the messages in raw XML or even some custom format if you're willing to write the serialization module.
The second option is to use the server mechanism of hooks and handlers (also available in ejabberd), which can trigger a server action on events like "user sent a message", "user logged in", "user logged out", ... This, however, requires a server side extension written in Erlang. In the simplest case the extension could forward any interesting event (with message content and metadata) via AMQP or just call some external HTTP/REST API - that way the real work is carried out by the workers giving you the freedom with regard to implementation language. This options also doesn't require to enable mod_mam or set up a database for message persistency (which you could still have with a persistent message queue...).
In general, the idea is perfectly feasible.
Generally, the most common XMPP extension use to build messaging systems for machines-to-machines, internet of things, microservices, etc is PubSub, as defined in XEP-0060.
This is a module you can enable in ejabberd. It is API based, so you can even customize the behaviour of that module to your application specific.
Pubsub basically allows to decouple senders and receivers and is especially designed for that use case.
Here are the details of my use case:
What's my data..
There would be user experiences, error report, state info and so on. The data is fragmented and may change in the future. So I plan to use NoSQL, maybe mongodb, to save data in the server.
What are the clients..
They are clients written in different languages, like C#, C++, LabVIEW and so on. Some don't even have an access to a mongodb driver, so of course it's not an option to communicate with database directly. And framework like below is needed.
Clients -> (Some protocol) -> Broker -> Database.
As those clients are not web client, so common web server using http may not suit for my case, right? Is there any suggestion for the protocol, broker and database, Or even a new framework.
My goal is to make the clients can send data as convenient as possible.
Thank you!
This is not really new, but a message driven application, which is a well understood pattern.
I did this mostly in Java, so I will stick to this language here.
A broker alone would be not enough here. Let us say you use Apache ActiveMQ as you message broker, you would still need to get your data into the database, since MQ is... ...a message queue. So you need a part which gets the messages out of MQ, processes them according to your business rules and stores them in the (correct) database instance, and the correct collection/bucket/table. Of course you could write this part by hand, but that would be pretty much reinventing the wheel. There is a notion of a "message routing and mediation engine", and the most commonly suggested here is Apache Camel, which has quite some components to communicate with databases and other so called consumers and producers. And that is the key point. In general, if possible, your clients should send their data to the message broker directly. But, if they can't, they can simply send text files or make REST calls – there are actually too many options to list here. This incoming data can be preprocessed and normalized to your standard format by a "route" in Apache Camel (a set of a consumer, conversion rules and a producer, in it's simplest form) and send as an AMQP message to MQ. From there, another Camel route can process the AMQP messages, apply your business rules and store the data in the database... ...or whatever else may come to your mind (for example sending an email).
So this solution supports a multitude of protocols for incoming and outgoing messages (as long as they are supported by Camel) and you have your business rules in a centralized and well defined location.
To implement this, I'd strongly suggest using Apache ServiceMix, which is a distribution of ActiveMQ, Camel and a system to manage the components and business rules.
Finally, web server with http protocal could suit for the use case, I think.
Mostly I want is a universal API for different kinds of clients to save data to cloud. Http has method GET, POST, PUT, DELETE, so with a RESTful API it is naturlly suitable for operate data, I think.
My solution at last is Node.js(Express) + Mongodb (a quite common group), and a RESTful API is provided via Express web server, clients can use http to operate data conviencely. Also, it is quite light weight and easy to get started.
Here is some tutorial: http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/
I'd like to use XMPP as the message bus for a desktop application. As the application would use the users existing XMPP account (GTalk or the like) and doesn't provide IM service I would like to make instances of my client invisible to other XMPP clients.
To do this I'm considering using client service discovery and privacy lists to block outgoing presence notifications to the full JIDs of clients other my own. I do however doubt the scalability and robustness of this approach. Is there a better way of accomplishing this?
EDIT:
I'm now thinking the closest I can get to this behaviour is to set a presence of away with a negative priority. This will hopefully minimise user confusion and work fairly universally.
XEP-0126 doesn't have the tools you need, since there's no way you'll find out about the other clients to which you have to direct presence... because they're invisible.
How about if all of your clients join a MUC room?
Does it make sense to create a service whose only responsibility is to send emails for other services?
Let me try to express my doubts more clearly and give a little bit of context. BTW, you can ignore the term "SOA" if you like. My intent in including it was to communicate that I am talking about a distributed system that is partitioned by function.
The reasons why I am uncertain as to whether an "Email Service" is appropriate or not are:
It provides a technical function
rather than an organization
function. It doesn't compose the
email messages, it just processes
them. Would it make sense to have
the Email Service compose the
messages by responding to domain
events? Would this be beneficial or
harmful?
It seems to introduce dependencies
into all other services which
utilize it. Particularly, I can't
see how one could avoid RPCish
interactions between the client and
the Email Service. Even if you use
messaging, the messages would be of
the command style (telling the Email
Service to send an email) which as I
understand it are inappropriate for
communications between services
since they increase coupling due to
the knowledge the client has to have
about the service it is consuming in
order for it to tell it what to do.
Unless of course the Email Service
composes the messages in response to
domain events from other services
(see point 1).
It is questionable how much
"service" it provides. In other
words, isn't the SMTP server already
the "Email Service"? Of course, the
custom "Email Service" might provide
things like queuing and parsing of
delivery reports. How much and what
should be in the Email Service for
it to really be necessary?
The alternative would be to have each service within the organization be responsible for sending out it's own email messages. However, this would mean that each service would have to be dependent on the SMTP server, but is that any different from being dependent on a custom "Email Service"? It would also mean that each service would be responsible for queuing and delivery management. Is this beneficial or harmful?
In addition, the email messages are considered domain entities, meaning that the organization is interested in the messages themselves in addition to the events that initiated them and the information that they carried. This means that users will be interested in viewing the messages that were sent out within context. For example you might look at a customer's account and ask to view the messages that were sent to that customer (these messages might include: account created confirmation, order placed confirmation, order shipped notification, experience feedback request, etc.).
I apologize if my question makes certain assumptions or is unclear, but based on what I've written, can anyone suggest an approach or discuss an approach that they have taken and how it worked out? I've already looked around SO for similar questions and googled on the topic but did not find anything that really applied, but if anyone can point out any resources I would greatly appreciate it. I would also be interested in answers that point out things that I might be overlooking or misunderstanding. Any sort of discussion on the matter seems valuable to me.
It depends on the context. What is a service? Is it a technical resource or a business resource?
If you were working at a technical level, partitioning a large technical soluiton into smaller parts (separation of concerns, etc) then I'd agree that an email service might well fit into this.
If the services are business services (e.g: "customer credit check") then an email service wouldn't fit into this.
And of course there's no reason why you can have both: a "top" layer of business services, implemented by a (technical) solution (that is composed of various sub-systems and layers) which includes a collection of technical services.