Skip to content

Commit bf75b82

Browse files
Merge pull request #21 from JoaoCaixinha/master
Added guaranteed delivery mode methods
2 parents 9d1db23 + 862facb commit bf75b82

6 files changed

Lines changed: 247 additions & 15 deletions

File tree

RCTRealtimeMessagingAndroid.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class RCTRealtimeMessagingAndroid extends React.Component {
3131
ortcClient.connect(config, this.id);
3232
}
3333

34-
3534
RTDisconnect(){
3635
ortcClient.disconnect(this.id);
3736
}
@@ -44,6 +43,14 @@ class RCTRealtimeMessagingAndroid extends React.Component {
4443
ortcClient.subscribeWithFilter(channel, subscribeOnReconnect, filter, this.id);
4544
}
4645

46+
RTSubscribeWithBuffer(channel, subscriberId){
47+
ortcClient.subscribeWithBuffer(channel, subscriberId, this.id);
48+
}
49+
50+
RTSubscribeWithOptions(options){
51+
ortcClient.subscribeWithOptions(options, this.id);
52+
}
53+
4754
RTSubscribeWithNotifications(channel, subscribeOnReconnect: boolean){
4855
ortcClient.subscribeWithNotifications(channel, subscribeOnReconnect, this.id);
4956
}
@@ -52,7 +59,11 @@ class RCTRealtimeMessagingAndroid extends React.Component {
5259
ortcClient.unsubscribe(channel, this.id);
5360
}
5461

55-
RTSendMessage(message, channel){
62+
RTSendMessage(channel, message, ttl){
63+
ortcClient.publish(channel, message, ttl, this.id);
64+
}
65+
66+
RTPublishMessage(message, channel){
5667
ortcClient.sendMessage(message, channel, this.id);
5768
}
5869

README.md

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ More information can be found on the
5252

5353

5454

55-
* Drag `RCTRealtimeMessagingAndroid.js` to the root of your project.
55+
* Drag `PROJECT_DIR/node_modules/react-native-realtimemessaging-android/RCTRealtimeMessagingAndroid.js` to the root of your project.
5656

5757
* **If you want to use push notifications**, set `MainActivity` extending `RealtimePushNotificationActivity`.
5858

@@ -124,6 +124,23 @@ RTRemoveEventListener removes an event registration. After this method when the
124124

125125
* onMessageWithFilter - Occurs when a message is received using `RTSubscribeWithFilter`. The event notification data is `{"message": message,"channel": channel, "filtered":true}`, where the filtered property indicates wheter the server was able to successfully filter the message.
126126

127+
* onMessageWithBuffer - Fired when a message was received in the specified channel subscribed with the `RTSubscribeWithBuffer`.
128+
- channel - The channel where the message was received
129+
- seqId - The message sequence id
130+
- message - The message received
131+
132+
* onMessageWithOptions - Fired when a message was received in the specified channel subscribed with the `RTSubscribeWithOptions`
133+
- msgOptions - Dictionary where the message data was received
134+
135+
-
136+
msgOptions = {
137+
channel, // Channel where the message was received
138+
seqId, // The message sequence id property
139+
filtered, // Indicates if server has filtered the message
140+
message // Content of the received message
141+
}
142+
143+
127144
* onPresence - Gets the subscriptions in the specified channel and if active the first 100 unique connection metadata:
128145
- On success -> `{"result": result}`
129146
- On error -> `{"error": error}`
@@ -247,6 +264,46 @@ Indicates whether the client should subscribe to the channel when reconnected (i
247264

248265
----------
249266

267+
#####RTSubscribeWithOptions(options)
268+
269+
Subscribes to a channel to receive messages sent to it with given options.
270+
271+
**Parameters**
272+
273+
* options - The subscription options dictionary, EX:
274+
options = {
275+
channel,
276+
subscribeOnReconnected, // optional, default = true,
277+
withNotifications (Bool), // optional, default = false, use push notifications as in subscribeWithNotifications
278+
filter, // optional, default = "", the subscription filter as in subscribeWithFilter
279+
subscriberId // optional, default = "", the subscriberId as in subscribeWithBuffer
280+
}
281+
282+
***Example:***
283+
284+
var options = {
285+
"channel":"YOUR_CHANNEL_NAME",
286+
"subscriberId":"CLIENT_SUBSCRIBER_ID",
287+
"filter":"MESSAGE_FILTER"
288+
}
289+
RCTRealtimeMessaging.RTSubscribeWithOptions(options);
290+
291+
----------
292+
293+
#####RTSubscribeWithBuffer(channel, subscriberId)
294+
295+
Subscribes to a channel to receive messages published to it.
296+
297+
**Parameters**
298+
299+
* channel - The channel name.
300+
* subscriberId - The subscriberId associated to the channel.
301+
302+
***Example:***
303+
304+
RCTRealtimeMessaging.RTSubscribeWithBuffer("MyChannel", "CLIENT_SUBSCRIBER_ID");
305+
306+
----------
250307

251308
##### RTSubscribeWithNotifications(channel, subscribeOnReconnect: boolean)
252309

@@ -295,6 +352,25 @@ Sends a message to a pub/sub channel.
295352

296353
----------
297354

355+
#####RTPublishMessage(channel, message, ttl, onPublishResultCallback)
356+
357+
Publish a message to a channel.
358+
359+
**Parameters**
360+
361+
* channel - The channel name.
362+
* message - The message to publish.
363+
* ttl - The message expiration time in seconds (0 for maximum allowed ttl).
364+
* onPublishResultCallback - callback returns error if message publish was not successful or published message unique id (seqId) if sucessfully published
365+
366+
***Example:***
367+
368+
RCTRealtimeMessaging.RTPublishMessage("MyChannel", "Hello World", ttl, function(error, seqId){
369+
370+
});
371+
372+
----------
373+
298374
##### RTEnablePresence(aPrivateKey, channel, aMetadata:boolean)
299375

300376
Enables presence for the specified channel with first 100 unique connection metadata.
@@ -308,8 +384,6 @@ Enables presence for the specified channel with first 100 unique connection meta
308384
* metadata - Sets to return metadata info
309385

310386

311-
312-
313387
***Example:***
314388

315389
RCTRealtimeMessaging.RTEventListener("onEnablePresence", function(event){

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-realtimemessaging-android",
3-
"version": "1.1.3",
3+
"version": "1.1.4",
44
"description": "The Realtime Framework Cloud Messaging Pub/Sub client for React-Native Android",
55
"main": "RCTRealtimeMessagingAndroid.js",
66
"scripts": {

reactnativemessagingandroid/src/main/java/co/realtime/reactnativemessagingandroid/GcmReceiver.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package co.realtime.reactnativemessagingandroid;
22

3-
import android.app.Activity;
4-
import android.app.Application;
53
import android.app.Notification;
64
import android.app.NotificationManager;
75
import android.app.PendingIntent;
@@ -11,7 +9,6 @@
119
import android.support.v4.app.NotificationCompat;
1210
import android.util.Log;
1311

14-
1512
import java.util.Random;
1613

1714
import ibt.ortc.extensibility.GcmOrtcBroadcastReceiver;
@@ -31,15 +28,15 @@ public void onReceive(Context context, Intent intent) {
3128
// if we are in the foreground, just surface the payload, else post it to the statusbar
3229
if (RealtimeMessagingAndroid.isOnForeground()) {
3330
extras.putBoolean("foreground", true);
34-
31+
RealtimeMessagingAndroid.sendExtras(extras);
3532
} else {
3633
extras.putBoolean("foreground", false);
3734
// Send a notification if there is a message
3835
if (extras.getString("M") != null && extras.getString("M").length() != 0) {
3936
createNotification(context, extras);
4037
}
4138
}
42-
RealtimeMessagingAndroid.sendExtras(extras);
39+
4340
}
4441
}
4542

reactnativemessagingandroid/src/main/java/co/realtime/reactnativemessagingandroid/RealtimeMessagingAndroid.java

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,21 @@
1313
import com.facebook.react.bridge.ReactContext;
1414
import com.facebook.react.bridge.ReactContextBaseJavaModule;
1515
import com.facebook.react.bridge.ReactMethod;
16+
import com.facebook.react.bridge.ReadableArray;
1617
import com.facebook.react.bridge.ReadableMap;
18+
import com.facebook.react.bridge.ReadableMapKeySetIterator;
19+
import com.facebook.react.bridge.ReadableType;
1720
import com.facebook.react.bridge.WritableMap;
1821
import com.facebook.react.bridge.WritableNativeMap;
1922
import com.facebook.react.modules.core.DeviceEventManagerModule;
2023

2124
import org.json.JSONException;
2225
import org.json.JSONObject;
2326

27+
import java.util.ArrayList;
2428
import java.util.HashMap;
2529
import java.util.Iterator;
30+
import java.util.List;
2631
import java.util.Map;
2732
import java.util.Objects;
2833

@@ -35,7 +40,10 @@
3540
import ibt.ortc.extensibility.OnDisconnected;
3641
import ibt.ortc.extensibility.OnException;
3742
import ibt.ortc.extensibility.OnMessage;
43+
import ibt.ortc.extensibility.OnMessageWithBuffer;
3844
import ibt.ortc.extensibility.OnMessageWithFilter;
45+
import ibt.ortc.extensibility.OnMessageWithOptions;
46+
import ibt.ortc.extensibility.OnPublishResult;
3947
import ibt.ortc.extensibility.OnReconnected;
4048
import ibt.ortc.extensibility.OnReconnecting;
4149
import ibt.ortc.extensibility.OnSubscribed;
@@ -217,6 +225,133 @@ public void disconnect(Integer id){
217225
}
218226
}
219227

228+
private Map<String, Object> recursivelyDeconstructReadableMap(ReadableMap readableMap) {
229+
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
230+
Map<String, Object> deconstructedMap = new HashMap<>();
231+
while (iterator.hasNextKey()) {
232+
String key = iterator.nextKey();
233+
ReadableType type = readableMap.getType(key);
234+
switch (type) {
235+
case Null:
236+
deconstructedMap.put(key, null);
237+
break;
238+
case Boolean:
239+
deconstructedMap.put(key, readableMap.getBoolean(key));
240+
break;
241+
case Number:
242+
deconstructedMap.put(key, readableMap.getDouble(key));
243+
break;
244+
case String:
245+
deconstructedMap.put(key, readableMap.getString(key));
246+
break;
247+
case Map:
248+
deconstructedMap.put(key, recursivelyDeconstructReadableMap(readableMap.getMap(key)));
249+
break;
250+
case Array:
251+
deconstructedMap.put(key, recursivelyDeconstructReadableArray(readableMap.getArray(key)));
252+
break;
253+
default:
254+
throw new IllegalArgumentException("Could not convert object with key: " + key + ".");
255+
}
256+
257+
}
258+
return deconstructedMap;
259+
}
260+
261+
private List<Object> recursivelyDeconstructReadableArray(ReadableArray readableArray) {
262+
List<Object> deconstructedList = new ArrayList<>(readableArray.size());
263+
for (int i = 0; i < readableArray.size(); i++) {
264+
ReadableType indexType = readableArray.getType(i);
265+
switch(indexType) {
266+
case Null:
267+
deconstructedList.add(i, null);
268+
break;
269+
case Boolean:
270+
deconstructedList.add(i, readableArray.getBoolean(i));
271+
break;
272+
case Number:
273+
deconstructedList.add(i, readableArray.getDouble(i));
274+
break;
275+
case String:
276+
deconstructedList.add(i, readableArray.getString(i));
277+
break;
278+
case Map:
279+
deconstructedList.add(i, recursivelyDeconstructReadableMap(readableArray.getMap(i)));
280+
break;
281+
case Array:
282+
deconstructedList.add(i, recursivelyDeconstructReadableArray(readableArray.getArray(i)));
283+
break;
284+
default:
285+
throw new IllegalArgumentException("Could not convert object at index " + i + ".");
286+
}
287+
}
288+
return deconstructedList;
289+
}
290+
291+
292+
@ReactMethod
293+
public void subscribeWithOptions(ReadableMap options, Integer id){
294+
Map newOptions = recursivelyDeconstructReadableMap(options);
295+
OrtcClient client = null;
296+
if (queue.containsKey(id)) {
297+
client = queue.get(id);
298+
client.subscribeWithOptions(newOptions, new OnMessageWithOptions() {
299+
@Override
300+
public void run(OrtcClient sender, Map msgOptions) {
301+
String thisId = "" + RealtimeMessagingAndroid.getKeyByValue(queue, sender);
302+
WritableMap params = new WritableNativeMap();
303+
params.putString("channel", (String)msgOptions.get("channel"));
304+
params.putString("message", (String)msgOptions.get("message"));
305+
if (msgOptions.containsKey("filtered"))
306+
params.putBoolean("filtered", (Boolean) msgOptions.get("filtered"));
307+
if (msgOptions.containsKey("seqId"))
308+
params.putString("seqId", (String) msgOptions.get("seqId"));
309+
310+
sendEvent(getReactApplicationContext(), thisId + "-onMessageWithOptions", params);
311+
}
312+
});
313+
}
314+
}
315+
316+
@ReactMethod
317+
public void subscribeWithBuffer(String channel, String subscriberId, Integer id){
318+
OrtcClient client = null;
319+
if (queue.containsKey(id)) {
320+
client = queue.get(id);
321+
client.subscribeWithBuffer(channel, subscriberId, new OnMessageWithBuffer() {
322+
@Override
323+
public void run(OrtcClient sender, String channel, String seqId, String message) {
324+
String thisId = "" + RealtimeMessagingAndroid.getKeyByValue(queue, sender);
325+
WritableMap params = new WritableNativeMap();
326+
params.putString("channel", channel);
327+
params.putString("message", message);
328+
params.putString("seqId", seqId);
329+
sendEvent(getReactApplicationContext(), thisId + "-onMessageWithBuffer", params);
330+
}
331+
});
332+
}
333+
}
334+
335+
@ReactMethod
336+
public void publish(String channel, String message, Integer ttl, Integer id, final Callback callBack){
337+
if (queue.containsKey(id)) {
338+
final OrtcClient client = queue.get(id);
339+
client.publish(channel, message, ttl, new OnPublishResult() {
340+
@Override
341+
public void run(String error, String seqId) {
342+
String pError = "";
343+
String pSeqId = "";
344+
if (error != null)
345+
pError = error;
346+
if (seqId != null)
347+
pSeqId = seqId;
348+
callBack.invoke(pError, pSeqId);
349+
}
350+
});
351+
}
352+
}
353+
354+
220355
@ReactMethod
221356
public void subscribeWithFilter(String channel, Boolean subscribeOnReconnect, String filter, Integer id){
222357
OrtcClient client = null;
@@ -461,6 +596,10 @@ private static JSONObject convertBundleToJson(Bundle extras)
461596
}
462597
else{
463598
String message = extras.getString("M");
599+
if (message.charAt(0) == '#'){
600+
String seqId = message.substring(message.indexOf("#") + 1,message.indexOf(":"));
601+
json.put("seqId", seqId);
602+
}
464603
String newMsg = message.substring(message.indexOf("_", message.indexOf("_") + 1) + 1);
465604
json.put("message", newMsg);
466605
}
@@ -502,8 +641,16 @@ public void sendJavascript(JSONObject json) {
502641
gCachedExtras = null;
503642
} catch (JSONException ex) {
504643
WritableMap params = new WritableNativeMap();
505-
params.putString("message", json.getString("message"));
506-
params.putString("channel", json.getString("channel"));
644+
645+
Iterator<String> iter = json.keys();
646+
while (iter.hasNext()) {
647+
String key = iter.next();
648+
try {
649+
params.putString(key, json.getString(key));
650+
} catch (JSONException e) {
651+
// Something went wrong!
652+
}
653+
}
507654

508655
if (queue != null){
509656
for (int id : this.queue.keySet()){

0 commit comments

Comments
 (0)