Receive offline messages with Quickblox - chat

Users do not receive offline messages when they get online.
Could you please explain why users do not receive offline messages?

I used below query to fetch the previous messages.
let resPage = QBResponsePage(limit:100, skip:self.messageHandler.messageArray.count)
let parameters = ["sort_desc" : "date_sent"]
QBRequest.messagesWithDialogID(createdDialog.ID,
extendedRequest: parameters,
forPage: resPage,
successBlock:
{(response: QBResponse, messages: [QBChatMessage]?, responcePage: QBResponsePage?) in
/*** You will get all the previous messages ***/
},
errorBlock: {(response: QBResponse!) in
/*** Some error occured while getting messages ***/
})

Related

solclient send request resulting success and fail at the same time

I'm starting a new project with Solace as the load balancer. As I follow the guideline on the official doc to build a service that can send requests to Solace, I encounter a weird issue where my request is successful and fails simultaneously. Here's my code
function initSolace(pass: string) {
var factoryProps = new solace.SolclientFactoryProperties();
factoryProps.profile = solace.SolclientFactoryProfiles.version10;
solace.SolclientFactory.init(factoryProps);
session = solace.SolclientFactory.createSession({
"url": "ws://localhost:8008",
"userName": "tech_core",
"vpnName": "testing",
"password": pass
}, new solace.MessageRxCBInfo(messageRxCb));
session.on(solace.SessionEventCode.UP_NOTICE, function (sessionEvent: any) {
requestData(10000).subscribe();
});
session.connect();
}
async function messageRxCb(session: any, message: any) {
message = Parser.decodeBinaryAttachmentToPb(message, pnlPb.RespPnl);
console.log('result from RxCb', message); // I got the correct response here
}
function requestData(timeout = 10000) {
return new Observable(subscriber => {
const parsedPayload = Parser.createPb({displayCurrency: 'USD'}, pnlPb.ReqPnl);
const msg = Parser.encodePbToBinaryAttachment(parsedPayload, pnlPb.ReqPnl);
const request = solace.SolclientFactory.createMessage();
request.setDestination(solace.SolclientFactory.createTopicDestination('my/testing/topic'));
request.setDeliveryMode(solace.MessageDeliveryModeType.DIRECT);
request.setDeliverToOne(true);
request.setBinaryAttachment(msg);
session.sendRequest(request, timeout,
(ses: any, message: any) => {
console.log('SUCCESS', message);
subscriber.next(message);
},
(ses: any, event: any) => {
console.error('FAIL', event); // I got a timeout error here
subscriber.error(event);
},
'correlation test'
)
});
}
As I run the code, I gets the timeout error from the requestData function AND the correct data from the messageRxCb function as well.
How does this happening? Did I miss any config here?
The Request-Reply pattern is a closely coupled communication pattern.
Every request that is posted by the requestor requires a response from the replier within the timeout specified.
I see from your code sample that you have configured a timeout of 10000ms. What it means is that every request that is posted should receive an incoming reply within 10000ms. If this response is not received, then it would result in the timeout error that you see in the console.
The reason why you see that the request is successfull and the error is because while the request has been successfully posted, a reply was not received within the specified timeout.
Do you already have a replier setup for this interaction? If not then I would suggesting setting up a simple boilerplate replier listening on this and testing the flow again.
Additionally, it would be good coding practise to handle the timeout error in a functionally appropriate manner.
Regards
Hari

CloudKit Batch Error: Previous Error in Atomic Zone

I am attempting to save a CKRecord using a CKModifyRecordsOperation and every time I try it, I get this initial error:
["CKErrorDescription": Failed to modify some records,
"CKPartialErrors": {
"CKRecordID: 0x60c000034000; recordName=ABC, zoneID=workspaceZone:DEF" = "CKError 0x60c000257340: \"Batch Request Failed\" (22/2024); \"Record CKRecordID: 0x7fb2f6998a60; recordName=ABC, zoneID=workspaceZone:DEF will not be saved because of previous error in atomic zone\"";
},
"NSDebugDescription": CKInternalErrorDomain: 1011, "NSUnderlyingError": CKError 0x60c000248af0: "Partial Failure" (1011); "Failed to modify some records"; partial errors: {
... 1 "Batch Request Failed" CKError's omited ...
},
"NSLocalizedDescription": Failed to modify some records]
I then parse the individual errors of the batch like this:
if let errorItems = error.partialErrorsByItemID {
for item in errorItems{
if let itemError = item.value as? CKError{
print("::: Individual Error in Batch :::")
print(itemError)
print(":::::")
}
}
}
But all the individual error says is:
CKError(_nsError: CKError 0x60c000257340: "Batch Request Failed" (22/2024); "Record CKRecordID: 0x7fb2f6998a60; recordName=GHI, zoneID=workspaceZone:JKL will not be saved because of previous error in atomic zone")
The CloudKit server log just says it's a BAD_REQUEST which isn't very helpful either.
Is there a way to get more details as to what's wrong with my record?
This just means one of your requests failed. You're doing a batch request with one or more requests. If one fails, CloudKit fails all of the requests to keep things atomic.
So, you should subscribe to errors on each record with perRecordCompletionBlock. Then, you can see which record is failing and why. You should print out the userInfo dictionary of the error for more detailed information.

PubNub to server data transfer

I am building an IoT application. I am using PubNub to communicate between the harware and the user.
Now I need to store all the messages and data coming from the hardware and from the user in a central server. We want to do a bit of machine learning.
Is there a way to do this other than having the server subscribe to all the output channels (There will be a LOT of them)?
I was hoping for some kind of once-a-day data dump involving the storage and playback module in PubNub
Thanks in advance
PubNub to Server Data Transfer
Yes you can perform once-a-day data dumps involving the storage and playback feature.
But first check this out! You can subscribe to Wildcard Channels like a.* and a.b.* to receive all messages in the hierarchy below. That way you can receive messages on all channels if you prefix each channel with a root channel like: root.chan_1 and root.chan_2. Now you can subscribe to root.* and receive all messages in the root.
To enable once-a-day data dumps involving Storage and Playback, first enable Storage and Playback on your account. PubNub will store all your messages on disk over multiple data centers for reliability and read latency performance boost. Lastly you can use the History API on your server to fetch all data stored as far back as forever as long as you know the channels to fetch.
Here is a JavaScript function that will fetch all messages from a channel.
Get All Messages Usage
get_all_history({
limit : 1000,
channel : "my_channel_here",
error : function(e) { },
callback : function(messages) {
console.log(messages);
}
});
Get All Messages Code
function get_all_history(args) {
var channel = args['channel']
, callback = args['callback']
, limit = +args['limit'] || 5000
, start = 0
, count = 100
, history = []
, params = {
channel : channel,
count : count,
callback : function(messages) {
var msgs = messages[0];
start = messages[1];
params.start = start;
PUBNUB.each( msgs.reverse(), function(m) {history.push(m)} );
callback(history);
if (history.length >= limit) return;
if (msgs.length < count) return;
count = 100;
add_messages();
},
error : function(e) {
log( message_out, [ 'HISTORY ERROR', e ], '#FF2262' );
}
};
add_messages();
function add_messages() { pubnub.history(params) }
}

Play framework 2.2 single websocket messages dispatching

In play framework we can see websocket-chat application that shows us usage of Concurrent.broadcast to handle websocket messages.
But I want to use websockets to send messages to each connected websocket independently. Simpliest example is something like private messages, when user sends message like: {user: "First", to: "Second", message: "Hi"}.
I looked at object play.api.libs.iteratee.Concurrent, looks like most suitable there is Concurrent.unicast to do this. But when we have Concurrent.broadcast - we have channel where we can push messages. In case of Concurrent.unicast - we have just Enumerator.
So, how can I dispatch private messages between websockets with Play Framework 2.2 in Scala?
I found another way to archive the private messaging problem out from the source code of the play framework sample. By using a filtered enumerator for each user:
val filteredEnumerator = enumerator &> Enumeratee.filter[JsValue]( e => {
if ( (e \ "kind").as[String] == "talk") {
val isToAll = (e \ "recipient").as[String] == "all"
val isToRecipient = (e \ "recipient").as[String] == username
val isFromRecipient = (e \ "user").as[String] == username
isToAll || isToRecipient || isFromRecipient
} else {
true
}
})
sender ! Connected(filteredEnumerator)
So, the message is being passed to the enumerator if the kind is "talk" (we only want to filter the messages), recipient is "all", recipient is the username itself or if user is the username itself so the person sent the message also sees the message.
the reply in the Chat room application is sent to All users in the Room via:
// Send a Json event to all members
public void notifyAll(String kind, String user, String text) {
So if you would like to implement a private message then you will have to implement "notify" method that will send message only to one specific user. Say something like:
// Send a Json event to all members
public void notify(String kind, String user, String userTo, String text) {
for(WebSocket.Out<JsonNode> channel: members.values()) {
ObjectNode event = Json.newObject();
event.put("kind", kind);
event.put("user", user);
event.put("message", text);
ArrayNode m = event.putArray("members");
m.add(userTo);
channel.write(event);
}

How to intercept Error handling in SmartGWT RPCManager

I'm using SmartGWT with RestDataSource. Whenever I lose internet connection, I get an SC.warn window with:
Server returned TRANSPORT_ERROR with no error message
I have tried to intercept this message to create a more friendly message, by adding a Callback handler for RPCManager like so:
RPCManager.setHandleTransportErrorCallback(new HandleTransportErrorCallback() {
public void handleTransportError(int transactionNum, int status,
int httpResponseCode, String httpResponseText) {
System.err.println("Transaction number: "+transactionNum);
System.err.println("Status: "+status);
System.err.println("Response code: "+httpResponseCode);
System.err.println("Response text:"+httpResponseText);
SC.warn("You have no internet connection.");
}
});
However, the Error messages print, and my warn message shows, but so does the system warn message above!
Keep in mind that I'm using a RestDataSource and not directly connecting to server with RPCManager.
How can I intercept this error message?
Thanks
Try instead RPCManager.setHandleErrorCallback(..).