Implementing Parses' channel logic with Amazon SNS - swift

On Parse (that I now have to leave behind) I had the ability to set multiple channels per installation and then target specific ones in my push notifications.
What is the best way to do this with SNS? At first I thought about topics, but there is a limitation to these.Another problem with topics is that the topic has to pre exist: On Parse you just mentioned a channel and you could then query and filter the Push recipients.
Should I create a similar experience manually using DynamoDB and keep the device token (as a primary key) and then the subscribed channels? This way when I want to send custom push messages I will have to query DB for the specific devices that contain that channel?
Hope someone has already dealt with this before.

Related

While using Offline data sync with Azure Mobile Apps SDK Can I control the order in which the table are synced?

We are generating the Primary Keys from(GUID) from client side and passing to server.
From some of the articles and blogs we came to know that Azure client sdk pushes the records in random order.
We have created a 2 tables with relations and tested this in offline mode and it works well. So we would like to confirm if the latest client side sdk has done some code fix to send the records in some order.
I wonder why can't they create a queue so that it will push the first in first out manner.
Since we have foriegn key relations in server side we need to push the inserts in an orderly manner, is there any mechanism to make this pushes to server in a specified order?
is there any mechanism to make this pushes to server in a specified order?
We could get the answer from this book-chapter3/relationships/.
The former is generally handled for you. If you InsertAsync a tag in offline mode, it will be placed into the operations queue prior to anything that uses it. Since the operations queue is processed in order, the tag will be sent to the backend prior to any record updates that would use it.
Note: Prefer handling tables individually and handling relationship management on the mobile client manually. This causes more code on the mobile client but makes the server much simpler by avoiding most of the complexity of relationships.

Is there any way to avoid evaluation of new subscriptions over existing entities?

When I append a new subscription in ORION, it automatically evaluates the condition and it invoques the designed end-point for that. I want that the new subscription affects only entities appended later.
Is there any way to avoid it or I have to control this at end-point level?
Related to this, is there any batch option to create several subscriptions at same time for a initial load of the platform?
Orion Version: 1.2.0
Regarding initial notification:
No, it isn't.
We understand that for some uses cases this is not convenient. However, behaving in the opossite way ruins another uses cases which need to know the "inicial state" before starting getting notifications corresponding to actual changes. The best solution to make everybody happy is to make this configurable, so each client can chose what it prefers. This feature is currently in our roadmap (see this issue in github.com).
While this gets implemented in Orion, in your case maybe a possible workaround is just ignore the first received nofitication belonging to a subscription (you can identify the subscription to which one notification belongs by the subscriptionId field in the notification payload). All the following notifications beloning to that subscription will correspond to actual changes.
Regarding batch option to create several subscriptions
No, there isn't any operation like that.
EDIT: the posibility of avoiding initial notification has been finally implemented at Orion. Details are at this section of the documentation. It is now in the master branch (so if you use fiware/orion:latest docker you will get it) and will be include in next Orion version (2.2.0).

How to combine websockets and http to create a REST API that keeps data up to date? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am thinking about buildning a REST API with both websockets and http where I use websockets to tell the client that new data is available or provide the new data to the client directly.
Here are some different ideas of how it could work:
ws = websocket
Idea A:
David get all users with GET /users
Jacob add a user with POST /users
A ws message is sent to all clients with info that a new user exist
David recive a message by ws and calls GET /users
Idea B:
David get all users with GET /users
David register to get ws updates when a change is done to /users
Jacob add a user with POST /users
The new user is sent to David by ws
Idea C:
David get all users with GET /users
David register to get ws updates when a change is done to /users
Jacob add a user with POST /users and it gets the id 4
David receive the id 4 of the new user by ws
David get the new user with GET /users/4
Idea D:
David get all users with GET /users
David register to get ws updates when changes is done to /users.
Jacob add a user with POST /users
David receive a ws message that changes is done to /users
David get only the delta by calling GET /users?lastcall='time of step one'
Which alternative is the best and what are the pros and cons?
Is it another better 'Idea E'?
Do we even need to use REST or is ws enought for all data?
Edit
To solve problems with data getting out of sync we could provide the header"If-Unmodified-Since"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Sinceor "E-Tag" https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag or both with PUT requests.
Idea B is for me the best, because the client specifically subscribes for changes in a resource, and gets the incremental updates from that moment.
Do we even need to use REST or is ws enought for all data?
Please check: WebSocket/REST: Client connections?
I don't know Java, but I worked with both Ruby and C on these designs...
Funny enough, I think the easiest solution is to use JSON, where the REST API simply adds the method data (i.e. method: "POST") to the JSON and forwards the request to the same handler the Websocket uses.
The underlying API's response (the response from the API handling JSON requests) can be translated to any format you need, such as HTML rendering... though I would consider simply returning JSON for most use cases.
This helps encapsulate the code and keep it DRY while accessing the same API using both REST and Websockets.
As you might infer, this design makes testing easier, since the underlying API that handles the JSON can be tested locally without the need to emulate a server.
Good Luck!
P.S. (Pub/Sub)
As for the Pub/Sub, I find it best to have a "hook" for any update API calls (a callback) and a separate Pub/Sub module that handles these things.
I also find it more resource friendly to write the whole data to the Pub/Sub service (option B) instead of just a reference number (option C) or an "update available" message (options A and D).
In general, I also believe that sending the whole user list isn't effective for larger systems. Unless you have 10-15 users, the database call might be a bust. Consider the Amazon admin calling for a list of all users... Brrr....
Instead, I would consider dividing this to pages, say 10-50 users a page. These tables can be filled using multiple requests (Websocket / REST, doesn't matter) and easily updated using live Pub/Sub messages or reloaded if a connection was lost and reestablished.
EDIT (REST vs. Websockets)
As For REST vs. Websockets... I find the question of need is mostly a subset of the question "who's the client?"...
However, once the logic is separated from the transport layer, than supporting both is very easy and often it makes more sense to support both.
I should note that Websockets often have a slight edge when it comes to authentication (credentials are exchanged once per connection instead of once per request). I don't know if this is a concern.
For the same reason (as well as others), Websockets usually have an edge with regards to performance... how big an edge over REST depends on the REST transport layer (HTTP/1.1, HTTP/2, etc').
Usually these things are negligible when it comes time to offer a public API access point and I believe implementing both is probably the way to go for now.
To summarize your ideas:
A: Send a message to all clients when a user edits data on the server. All users then request an update of all data.
-This system may make a lot of unnecessary server calls on behalf of clients who are not using the data. I don't recommend producing all of that extra traffic as processing and sending those updates could become costly.
B: After a user pulls data from the server, they then subscribe to updates from the server which sends them information about what has changed.
-This saves a lot of server traffic, but if you ever get out of sync, you're going to be posting incorrect data to your users.
C: Users who subscribe to data updates are sent information about which data has been updated, then fetch it again themselves.
-This is the worst of A and B in that you'll have extra round trips between your users and servers just to notify them that they need to make a request for information which may be out of sync.
D: Users who subscribe to updates are notified when any changes are made and then request the last change made to the server.
-This presents all of the problems with C, but includes the possibility that, once out of sync, you may send data that will be nonsense to your users which might just crash the client side app for all we know.
I think that this option E would be best:
Every time data changes on the server, send the contents of all the data to the clients who have subscribed to it. This limits the traffic between your users and the server while also giving them the least chance of having out of sync data. They might get stale data if their connection drops, but at least you wouldn't be sending them something like Delete entry 4 when you aren't sure whether or not they got the message that entry 5 just moved into slot 4.
Some Considerations:
How often does the data get updated?
How many users need to be updated each time an update occurs?
What are your transmission
costs? If you have users on mobile devices with slow connections, that will affect how often and how much you can afford to send to them.
How much data gets updated in a given update?
What happens if a user sees stale data?
What happens if a user gets data out of sync?
Your worst case scenario would be something like this: Lots of users, with slow connections who are frequently updating large amounts of data that should never be stale and, if it gets out of sync, becomes misleading.
I personally have used Idea B in production and am very satisfied with the results. We use http://www.axonframework.org/, so every change or creation of an entity is published as an event throughout the application. These events are then used to update several read models, which are basically simple Mysql tables backing one or more queries. I added some interceptors to the event processors that update these read models so that they publish the events they just processed after the data is committed to the DB.
Publishing of events is done through STOMP over web sockets. It is made very simple is you use Spring's Web Socket support (https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). This is how I wrote it:
#Override
protected void dispatch(Object serializedEvent, String topic, Class eventClass) {
Map<String, Object> headers = new HashMap<>();
headers.put("eventType", eventClass.getName());
messagingTemplate.convertAndSend("/topic" + topic, serializedEvent, headers);
}
I wrote a little configurer that uses Springs bean factory API so that I can annotate my Axon event handlers like this:
#PublishToTopics({
#PublishToTopic(value = "/salary-table/{agreementId}/{salaryTableId}", eventClass = SalaryTableChanged.class),
#PublishToTopic(
value = "/salary-table-replacement/{agreementId}/{activatedTable}/{deactivatedTable}",
eventClass = ActiveSalaryTableReplaced.class
)
})
Of course, that is just one way to do it. Connecting on the client side may look something like this:
var connectedClient = $.Deferred();
function initialize() {
var basePath = ApplicationContext.cataDirectBaseUrl().replace(/^https/, 'wss');
var accessToken = ApplicationContext.accessToken();
var socket = new WebSocket(basePath + '/wss/query-events?access_token=' + accessToken);
var stompClient = Stomp.over(socket);
stompClient.connect({}, function () {
connectedClient.resolve(stompClient);
});
}
this.subscribe = function (topic, callBack) {
connectedClient.then(function (stompClient) {
stompClient.subscribe('/topic' + topic, function (frame) {
callBack(frame.headers.eventType, JSON.parse(frame.body));
});
});
};
initialize();
Another option is to use Firebase Cloud Messaging:
Using FCM, you can notify a client app that new email or other data is
available to sync.
How does it work?
An FCM implementation includes two main components for sending and
receiving:
A trusted environment such as Cloud Functions for Firebase or an app server on which to build, target and send messages.
An iOS, Android, or Web (JavaScript) client app that receives messages.
Client registers its Firebase key to a server. When updates are available, server sends push notification to the Firebase key associated with the client. Client may receive data in notification structure or sync it with a server after receiving a notification.
Generally you might have a look at current "realtime" web frameworks like MeteorJS which tackle exactly this problem.
Meteor in specific works more or less like your example D with subscriptions on certain data and deltas being sent out after changes only to the affected clients. Their protocol used is called DDP which additionally sends the deltas not as overhead prone HTML but raw data.
If websockets are not available fallbacks like long polling or server sent events can be used.
If you plan to implement it yourself i hope these sources are some kind of inspiration how this problem has been approached. As already stated the specific use case is important
The answer depends on your use case. For the most part though I've found that you can implement everything you need with sockets. As long as you are only trying to access your server with clients who can support sockets. Also, scale can be an issue when you're using only sockets. Here are some examples of how you could use just sockets.
Server side:
socket.on('getUsers', () => {
// Get users from db or data model (save as user_list).
socket.emit('users', user_list );
})
socket.on('createUser', (user_info) => {
// Create user in db or data model (save created user as user_data).
io.sockets.emit('newUser', user_data);
})
Client side:
socket.on('newUser', () => {
// Get users from db or data model (save as user_list).
socket.emit('getUsers');
})
socket.on('users', (users) => {
// Do something with users
})
This uses socket.io for node. I'm not sure what your exact scenario is but this would work for that case. If you need to include REST endpoints that would be fine too.
With all great information all the great people added before me.
I found that eventually there is no right or wrong, its simply goes down to what suits your needs:
lets take CRUD in this scenario:
WS Only Approach:
Create/Read/Update/Deleted information goes all through the websocket.
--> e.g If you have critical performance considerations ,that is not
acceptable that the web client will do successive REST request to fetch
information,or if you know that you want the whole data to be seen in
the client no matter what was the event , so just send the CRUD events
AND DATA inside the websocket.
WS TO SEND EVENT INFO + REST TO CONSUME THE DATA ITSELF
Create/Read/Update/Deleted , Event information is sent in the Websocket,
giving the web client information that is necessary to send the proper
REST request to fetch exactly the thing the CRUD that happend in server.
e.g. WS sends UsersListChangedEvent {"ListChangedTrigger: "ItemModified" , "IdOfItem":"XXXX#3232" , "UserExtrainformation":" Enough info to let the client decide if it relevant for it to fetch the changed data"}
I found that using WS [Only for using Event Data] and REST
[To consume the data ]is better because:
[1] Separation between reading and writing model, Imagine you want to add some runtime information when your data is retrieved when its read from REST , that is now achieved because you are not mixing Write & Read models like in 1.
[2] Lets say other platform , not necessarily web client will consume this data.
so you just change the Event trigger from WS to the new way, and use REST to
consume the data.
[3] Client do not need to write 2 ways to read the new/modified data.
usually there is also code that reads the data when the page loads , and not
through the websocket , this code now can be used twice , once when page
loads , and second when WS triggered the specific event.
[4] Maybe the client do not want to fetch the new User because its showing currently only a view of old Data[E.g. users] , and new data changes is not in its interest to fetch ?
i prefer the A, it allows client the flexibility whether or not to update the existing data.
also with this method, implementation and access control becomes much more easier.
for example you can simply broadcast the userUpdated event to all users, this saves having a client list for do specific broadcasts and the Access Controls and Authentications applied for your REST Route wont have to change to reapplied again because the client is gonna make a GET request again.
Many things depends on the what kind of application you are making.

Secure request from iPhone to Server

I'm currently working on an app sending request on a server for a voting system. The problem is that people can vote without registration but I don't want them to vote multiple time and I don't know how to secure this. I thought about a key system (generated in the app and verified on the server), but I'm not sure that this is the best solution.
What should I do ?
There are two possible solutions to this.
1) Handle the code that detects the duplicate vote on the server
For each vote cast the server stores the device id against the identifier of the vote. The server ignores any duplicate votes cast for that topic and sends back a "failure" response. This is handled by the device.
Pros: Centralized voting logic. Change it once on the server and all versions of apps in the wild conform.
Cons: You have to build the server logic. If you're more comfortable with ObjectiveC this may be an issue. You have to maintain the database of voting topics and devices that have voted.
2) Handle the code that detects the duplicate vote on the device
The device downloads a list of all the voting topics then filters them by the topics that have already been voted on. When a user votes on a topic then the device adds the id of that topic to the filter list.
Pros: No database maintenance beyond having a list of voting topics.
Cons: Users could remove the app, reinstall and vote again. If you want to change the voting logic (e.g. you want people to be able to vote twice on a topic) you have to update all the existing apps.
Admittedly putting the voting logic in the app makes the app more complex. However that added complexity has to be absorbed somewhere - either in the app or on the server.

Creating a constantly updating feed like Twitter

I'd like to have something in my app that is just like Twitter but not Twitter. Basically it will be a place people can submit messages and do not need an account. They only way they can submit is through the app. I want other app users to see the submitted messages nearly immediate. I believe push notification can do that sort of work but do I need push notification for this? How does Twitter do it?
-- EDIT --
After reading some of the responses, push might be what I need. People will be submitting messages to my server often. If someone is watching the feed, they might see one new message per minute depending on the query they are using. I'm thinking to go with a MySQL database, (which allows switching to cheaper non Windows servers w/o much hassle) and push notification. Are there any reasons those won't work for my scenario?
You only need push notification if you want the app to be able to receive new messages while closed.
Here's a rough description of one way to do this:
Your app sends a message via HTTP Post to your server.
Your server stores the message in a database, using the iPhones unique ID as an identifier.
Your app connects to the server frequently, asking for new messages.
If there are any new ones, the server hands the message to the app, which displays it.
This is approximately what twitter/iphone twitter apps do.
Your choices are fairly binary:
Use push notification
Use Polling
With Push Notification:
You control when you contact your users... Heavy Load means you can slow updates down to avoid taxing your infrastructure
Contrariwise, you have to push to clients that may not even be there anymore (And thus may need some sort of register model), high load may mean that clients don't get immediate update
You can leverage things like Amazon's EC2 to give you more processing power
Unless you're out of capacity, users are almost certain to be receiving updates as they happen
To pick up messages missed while offline, the SERVER needs to know what message was last successfully received, store older messages and forward many all at once
If you choose to use polling:
You must have a stable address to be polled
You need the ability to have lots of quick query connections checking for new data, then returning that data if required.
If your application becomes popular enough you may find you don't have enough resources
If your resources are taxed your application will go down, rather then just slow down
You don't need to register clients and keep track of their on/offline state
Parallelizing on the fly is a bit trickier
To pick up older messages, the CLIENT needs to know when they last received a message and then request the server send any message since that time
Both can be fast, but they come with different bandwidth and processing profiles. I prefer push for everything that's real-time.
Might want to take a look at XMPP.
Twitter doesn't really push events out to the iPhone in realtime. It's more like polling by the various clients.
If you really want instantaneous for the last mile you'll want to use push.
Twitter uses lots of servers and raid arrays to handle the load of millions of people posting 140 character messages. Twitter clients log in and request a list of updates for all of the people the user is following within a certain time frame.
Push wouldn't be a good candidate for this because it does not persist the "tweets". It is simply a notification mechanism. There is a text messaging app on the App Store (called Ping!) that relies completely on push notification for sending text messages. This seems to work fine, but if the developers are keeping track of the messages, it is all done on their servers. In their case push makes sense as you want to alert the user of a new message. In the case of a twitter clone, however, it would probably just annoy users if they got a new notification every time someone tweeted.
In the end you're better off just implementing it server side and then developing an iPhone client that logs in and retrieves the latest tweets for the people the user is following.