Do Parse Cloud Code triggers need response - ios

Since I'm kinda new to cloud code, I have the question mentioned above!
1) Do cloud code triggers, beforeSave - afterSave etc, need to call response.success and response.error when they are done?
2) If so, is it possible for the client to receive that response?
Edit: For the first question, I realised that it's necessary for the "before" triggers only...
The second question remains unanswered!

In a beforeSave() trigger, the response.sucess() is returned to the client like this.
It's only in case of error that it could be interesting to return a specific message (for a business validation before save for i.e)
So in your cloud code you could write :
Parse.Cloud.beforeSave("MyObject", function(request, response) {
//business validation then if fail :
response.error("there was an error blabla...");
}
});
Then the Client will receive a Parse Exception with the corresponding message

Related

Azure IoT SDK - async response to Direct Method

Similar to this question and solution: https://github.com/Azure/azure-iot-sdk-c/issues/1081
The caveat being I don't see how I can obtain the methodId necessary for delaying a response when using the convenience layer API. When the callback which was registered with IoTHubClient_SetDeviceMethodCallback() is called, setting payload response to NULL will result in no response being sent by SDK- I'd like to get the methodId in this callback to use later when response is ready.
I'd like to later call IoTHubClient_DeviceMethodResponse(), but how to obtain methodId necessary for this function?
Okay, I found the solution: need to register another callback to handle asynchronous direct methods. See: IoTHub_SetDeviceMethodCallbackEx()
https://learn.microsoft.com/en-us/azure/iot-hub/iot-c-sdk-ref/iothub-client-h/iothubclient-setdevicemethodcallback-ex

Make periodic HTTP requests with service worker

Is it possible to make HTTP requests in background with service worker, when users are not visiting my webpage. I want to make periodic requests to my webpage (e.g. 3 seconds)?
There is a feature called periodicSync, but i didn't understand how to use it.
I've not tried implementing this but for me the clearest overview has been this explanation.
Making periodic requests involves first handling the Service Worker ready event, invoking the periodicSync.register() function with config options. The register() function returns a Promise that allows you to deal with success or rejection of the periodic sync registration.
registration.periodicSync.register()
Pass a 'config' object parameter with the following properties:
tag
minPeriod
powerState
networkState
You may then register listeners against the periodicSync event. E.g (slightly simplified example based on the explanation.
self.addEventListener('periodicsync', function(event) {
if (event.registration.tag == 'my-tag') {
event.waitUntil(doTheWork()); // "do the work" asynchronously via a Promise.
}
else {
// unknown sync, may be old, best to unregister
event.registration.unregister();
}
});

Problems subscribing to a room (socket) with Socket.IO-Client-Swift and Swift, Sails.js on the Server

On Swift, I use
socket.on("test") {data, ack in
print(data)
}
In order to subscribe to a room (socket) on my Sails.js API.
When I broadcast a message from the server, with
sails.sockets.broadcast('test', { text : 'ok' })
the socket.on handler is never called.
However, if I set "log" TRUE to config when connecting my socket.io client from swift, in Socket-IO logs the message arrives.
What's wrong?
Eventually, I found my mistake:
The whole process I did is right:
(The request to join the room is done by the server, with sails.sockets.join)
Wrong thing was using socket.on with the ROOM NAME parameter.
I will explain it better, for others having same problem:
From Swift you should subscribe by making a websocket request to an endpoint on the server that accepts websocket requests (GET, POST, PUT). For example, you can make a POST request, passing in the room name into the body.
socket.emitWithAck("post", [
"room": "testroom",
"url": "/api/v1.0/roomsubscribing"
]).timingOut(after: 0) {data in
print("Server responded with \(data)")
}
On server side, inside the room-subscribing endpoint, you should have the following code:
roomSubscribing: function(req, res) {
if (!req.isSocket) {
return res.badRequest();
}
sails.sockets.join(req, req.params('room'), function(err) {
if (err) {
return res.serverError(err);
}
});
}
When the server want to broadcast some data to subscribers of the "testroom" room, the following code must be used:
sails.sockets.broadcast('testroom', { message: 'testmessage' }
Now on the swift's side you must use:
socket.on("message") { data, ack in
print(data)
}
in order to get the message handler to work. I thought you should use room name, instead you should use the KEY of the KEY/VALUE entry you used in your server when you broadcasted the data (in this case, "message").
I only have a small amount of experience with sockets, but in case nobody else answers...
I think you are missing step one of the three step socket process:
A client sends a message to the server asking to subscribe to a particular room.
The client sets up a socket.on to handle particular events from that room.
The server broadcasts an event in a particular room. All subscribers/clients with a .on for that particular event will react.
I could be wrong, but it sounds from your description like you missed step one. Your client has to send a message with io.socket, something like here, then your server has to use the socket request to have them join the room, something like in the example here.
(the presence of log data without the socket.on firing would seem to confirm that the event was broadcast in the room, but that client was not subscribed)
Good luck!

getting null response from recieveAndConvert() spring -amqp

I have created on replyQ and done biniding with one direct exchange.
Created the message by setting replyto property to "replyQ"
And sending the message on rabbit to the other service.
The service at other end getting the message and sending reply on given replyTo queue.
and now I am trying to read from a replyQ queue using
template.receiveAndConvert(replyQueue));
But getting null response and i can see the message in the replyQ.
That is the service is able to send the reply but am not able to read it from the given queue
Please help what is going wrong.
template.receiveAndConvert() is sync, blocked for some time one time function, where default timeout is:
private static final long DEFAULT_REPLY_TIMEOUT = 5000;
Maybe this one is your problem.
Consider to switch to ListenerContainer for continuous queue polling.
Another option is RabbitTemplate.sendAndReceive(), but yeah, with fixed reply queue you still get deal with ListenerContainer. See Spring AMQP Reference Manual for more info.
I don't know if this could help anyone, but I found out that declaring the expected Object as a parameter of a method listener did the work
#RabbitListener(queues = QUEUE_PRODUCT_NEW)
public void onNewProductListener(ProductDTO productDTO) {
// messagingTemplate.receiveAndConvert(QUEUE_PRODUCT_NEW) this returns null
log.info("A new product was created {}", productDTO);
}

A better way to detect a change in a parse class?

Currently I set up a timer that every 2 seconds makes a query to a parse class to see if any data has changed. If the data has changed it calls the refreshData method so my view can be updated with the new parse data.
So when ever data is updated in the parse class it will almost instantly be updated in the app.
The problem is this causes a lot of unnecessary web traffic, which I need to avoid.
What can I do to replace the timer with something that detects when data is changed in the parse class then tells the app to call the refreshData method?
afterSave Triggers
//this will trigger everytime the className objects has changed
Parse.Cloud.afterSave("className", function(request) {
//Do some stuff here //like calling http request or sending push 'data has changed' to installed mobile device
console.log("Object has been added/updated"+request.object.id);
});
https://parse.com/docs/js/guide#cloud-code-aftersave-triggers
You need to deploy first a cloud code then it will handle your problem :-)
In some cases, you may want to perform some action, such as a push, after an object has been saved. You can do this by registering a handler with the afterSave method. For example, suppose you want to keep track of the number of comments on a blog post. You can do that by writing a function like this:
Parse.Cloud.afterSave("Comment", function(request) {
query = new Parse.Query("Post");
query.get(request.object.get("post").id, {
success: function(post) {
post.increment("comments");
post.save();
},
error: function(error) {
console.error("Got an error " + error.code + " : " + error.message);
}
});
});
The client will receive a successful response to the save request after the handler terminates, regardless of how it terminates. For instance, the client will receive a successful response even if the handler throws an exception. Any errors that occurred while running the handler can be found in the Cloud Code log.
If you want to use afterSave for a predefined class in the Parse JavaScript SDK (e.g. Parse.User), you should not pass a String for the first argument. Instead, you should pass the class itself.
I'm not sure if my solution will fit with your needs, but using beforeSave trigger within CloudCode, combined to DirtyKeys will save you time and queries : http://blog.parse.com/learn/engineering/parse-objects-dirtykeys/
With DirtyKeys you can detect once some change was done on your class, and then you can build new trigger and do whatever you need once done.

Resources