Problem :
We are trying to make a chat application using AWS product AppSync and we want to achive the best performance but we're facing problem with real time subscriptions in AppSync and Graphql where a single user will need to handle hundereds of subscription in some cases which we think is not the best solution, what do you suggest ?
Problem Example:
Mutation{
addMessage(conversation_id=Int!, content:String!) : Message
}
Subscription{
subscribeForNewMessages(convesration_id: Int!):Message
#aws_subscribe(mutations: ["addMessage"])
}
the problem with this design is that the user need to invoke this subscription and keep listening for every single conversation, which we expect to be overwheelming the client in case if the conversations quantity is huge.
Questions :
Q1 :
What we are striving to achieve is one subscription for multiple (conversation_id)s, how this will be possible?
These folks (https://github.com/apollographql/apollo-client/issues/2633) are talking about something similar, we tested it and it doesn't work, is it a valid solution?
Q2:
Regarding Amplify; Will amplify perform well when listening for hundereds of subscription simulanuosly? does it make some sort of merging subscription and websockets or it will deal them separately?
Q3:
what are your comments about these designs? where there will be a service that will braodcast(invoke mutations with clients ids) the messages for chat participants , and the client will subscribe only for a single channel . like the following:
src2 : AWS AppSync for chatting application
src2 : Subscribe to a List of Group / Private Chats in AWS AppSync
Q1/Q2
You'll have to make multiple subscriptions and the aws ios/android/amplify sdks can handle subscription handshake protocols for real-time updates to data.
Take a look here
Q3
I recommend allowing clients to subscribe to specific channels (even if that means multiple subscriptions) so that the filtering logic can be done in the service rather than client side, reducing client side code which also means you don't have to worry about maintenance or scalability.
Related
Below is a typical GCP pubsub model:
My question: is it possible for one subscriber(application or job) to subscribe to multiple subscriptions? Like this:
I mean we can filter at the subscription level that one subscription takes one event type (A or B). I know it will be easier if we have two topics (Topic A and B) and create two subscriptions, but again, it will boil down to the same question, is it possible for one subscriber to subscribe to multiple subscriptions?
Or the only alternative way I can imagine is that at the subscriber level, I can classify the event type, A or B, but that requires the publisher to pass the attribute to the topic level.
I have the control of publisher and I just wanna do one Subscriber instead of multiple subscribers.
An application can subscribe to multiple subscriptions, yes. You would need to instantiate multiple instances of the subscriber client, one for each subscription for which you want to receive messages.
If you want the subscriber to be able to receive messages without knowing the names of all of the subscriptions, then you could use push subscriptions and set the endpoint to different subscriptions to the same URL. Then, the subscriber behind that URL would receive messages from the different subscriptions.
I have an e-commerce website and I want to implement a messaging solution between my clients, using ably.io. I am new to ably.io and also to pub/sub message pattern and need some advice to put me on the right track.
Let’s say I have 75,000 users on my website. Users can create an advertisement... if anyone is interested in the advertisement they should be able to message the advertiser.
This is the solution that comes to my mind after reading ably's documentation:
Since I have 75,000 users, I create 75,000 channels, 1 channel per user.
An user named Brian creates an advertisement on the website. Brian subscribes to BrianChannel to receive all messages on his own channel. Now Amy and Tom have seen Brian's advertisement and want to contact him, they publish a message on BrianChannel and Brian would receive the messages.
I am not sure if the above solution is the right approach?
If the above solution is the right way, I have 2 further questions:
Let's Brian uses JavaScript to subscribe to BrianChannel. Now Brian is obviously not online 24/7 - how should I handle his messages while he is offline?
I have 75,000 users registered on my website. At any point of time 5,000 users are online. Out of these 5000 users online, 20 users are actually messaging each other. Using my solution above, I should have 5,000 active channels for all the online users... Is there a way to reduce the number of active channels? Perhaps by periodically polling the channels?
This is Srushtika, Dev Advocate at Ably.
Your approach is correct and is in-fact the most commonly implemented one. i.e, each of your 75,000 users will have their own channels to which only they will be subscribed to. Any other client who wishes to send them a message, will attach to 'their' channel and publish messages to it. Since all users are always subscribed to their own channels, they will be able to receive any messages intended for them.
If any of your subscriber clients are not online at the time a message is to be sent to them, Ably's Realtime platform will, by default, retain it for 2min after which, if the subscriber client is still offline, the messages will be discarded. However, using the Persisted History feature, you can increase the time for which messages are retained to 24-72hrs.
Unfortunately, as of now, Ably doesn't offer a mechanism to detach from channels with no activity while the client is still online. But, this feature is coming soon. Keep an eye on our Engineering blog where we post all such updates.
Hope that answers your question.
When building a social application it's common to follow other users or topics as an indication of interest in updates by the user or topic. For example, following other users on Twitter, Friending other people on Facebook or liking a product or brand on Facebook.
Pusher has the concept of channels that you subscribe to. Channels are a human readable string that provide a logical identifier to information (e.g. "some-channel-name") and therefore seems to naturally suggest that in a social application any updates on a user or topic should be sent on a channel specific to that item (e.g. "userX-status-updates" or "myBrand-status-updates").
However, this raises concerns about how efficient it is to subscribe to multiple channels if a user is following a high number of other users or topic.
Therefore, what are the appropriate strategies for structuring channels in an social status update style application that uses Pusher?
The first thing to clarify is that you need a mapping of who you are following so for the purposes of this answer I'm going to assume that it's stored in a DB on the server. It also assumed that status updates are triggered as follows:
Client (userX posts status update) -> Your Server (sanitize & validate)
Your Server -> Pusher
Pusher -> Clients (users interested in updates from UserX)
There are two possible solutions to the channel information architecture problem:
Channel Per User Status: A user subscribes to a userX-status-updates channel for all the users that they follow and users trigger update events on their own status update channel.
Users I'm Following Channel: When a user posts a status update you look up who is following that user and publish the update on a users-you-follow-updates channel.
Strategy 1. is the most optimal solution as it keeps interactions with your own infrastructure an Pusher to a minimum.
Here's the detail on these two strategies:
1. Channel Per User Status
The assumption here is that subscribing to channels is costly but that not entirely correct. Channels are simply a way of routing events. However, if you are using authenticated channels (private & presence) you need to authenticate the subscription via your own server. If you use the Pusher WebSocket libraries "out of the box" each subscription will result in a request to your server. So, a user is following 1,000 users that's 1,000 requests to your server.
But, for the pusher-js library there is a multi-auth plugin that can batch the authentication requests into a single call.
There is also a BatchAuthorizer for the Pusher WebSocket Java library, but it's only a sample solution to this scenario.
2. Users I'm Following Channel
Note: although this is an option it's probably only appropriate for smaller numbers of users
In this scenario a user sends their status update to the server, the server performs a lookup of which users are interested in the update and triggers and update even on a channel for each interested user.
For example, give users UserA, UserB and UserC each of those users will subscribe to their own update channel; UserA-followers-updates, UserB-followers-updates, and UserC-followers-updates respectively. If each of these users follows UserZ then when UserZ makes as status update that update is published on each of those channels.
This may also sound inefficient, however it is possible to trigger the same event on 10 channels at a time. So in the above example it would only require one call to the Pusher HTTP API to send the status update to all interested users. More information on multi-channel event publishing here.
Setup:
I have setup a pubsub service wherein the publishers publish geolocation data at regular intervals.
The subscribers receive the location data of the publishers.
The subscribers are not presence subscribed, in the sense, the subscribers are not in the publishers rosters.
Problem:
The subscribers need to know the presence status of publishers.
Is there a way for the subscribers to know the presence status of publishers?
No, since there is no direct relationship between subscribers and publishers, which is typical of any pubsub design. To accomplish this the subscribers would need to know who the publishers are, which is not a good generic pubsub design.
It sounds like what you actually want is PEP (Personal Eventing Protocol), which is a subset of pubsub. In this case, the subscribers are subscribing to nodes belonging to the actual user they are interested in. If they are subscribed to the users presence, they automatically have access to the users nodes.
NOTE: I have recently found out that the newer version of the spec does in fact support an attribute that identifies the publisher. Thus making it feasible to get their presence, but you would still have to subscribe or query for it.
Actually I'm more interested in the techniques to use to achieve this task more than really building a chat system (which is an excellent concrete example). I see 2 parts:
The client needs to get registered somewhere, and we then need a unique ID per client.
The server should be able to send something to the client only from another client.
For the first part, I do not know how to get this unique id. Possibly using the new meteor auth kit ?
For the second part, I thought about building a per-client collection in which one and only one client will have access to, but it sounds heavy and In my opinion not really in the Meteor best practice. I then thought of adding a "from" and to "field" to a Message (see the regular chat example). This would do it but I'm wondering about the no privacy on them. Would a custom publish returning a filtered find do it or it is risky too i.e. would other client get the items too ? Something like:
Meteor.publish("message", function (clientID) {
return Messages.find({"dest":clientID }, {});
});
The latest Meteor todos example uses the new auth system to identify private todo entries. I would imagine that you could use the same mechanism to identify the originator and recipient of a private message in a chat like system.
Of course the filtering of which messages someone sees would need to be filtered on the server side to maintain privacy.