Friends and messages

@BPI @TangZhiLong Find the equivalent codes for swift

Introduction

Elastos Carrier provides features such as direct messaging (text or binary) to a peer, group messaging, or file transfer. This guide will show several of carrier’s main features.

Initialize carrier

Configure carrier options

Carrier needs a few options to be configured first. Mostly, we must tell him which bootstrap nodes it should use to start communicating with the rest of the P2P network.

 
public class DefaultCarrierOptions extends Carrier.Options {
    public DefaultCarrierOptions(String path) {
        super();

        setOptions(path);
    }

    private void setOptions(String path) {
        setUdpEnabled(true);
        setPersistentLocation(path); // path is used to cache carrier data for better performance

        ArrayList<BootstrapNode> arrayList = new ArrayList<>();
        BootstrapNode node;

        node = new BootstrapNode();
        node.setIpv4("13.58.208.50");
        node.setPort("33445");
        node.setPublicKey("89vny8MrKdDKs7Uta9RdVmspPjnRMdwMmaiEW27pZ7gh");
        arrayList.add(node);

        node = new BootstrapNode();
        node.setIpv4("18.216.102.47");
        node.setPort("33445");
        node.setPublicKey("G5z8MqiNDFTadFUPfMdYsYtkUDbX5mNCMVHMZtsCnFeb");
        arrayList.add(node);

        node = new BootstrapNode();
        node.setIpv4("52.83.127.216");
        node.setPort("33445");
        node.setPublicKey("4sL3ZEriqW7pdoqHSoYXfkc1NMNpiMz7irHMMrMjp9CM");
        arrayList.add(node);

        node = new BootstrapNode();
        node.setIpv4("52.83.127.85");
        node.setPort("33445");
        node.setPublicKey("CDkze7mJpSuFAUq6byoLmteyGYMeJ6taXxWoVvDMexWC");
        arrayList.add(node);

        node = new BootstrapNode();
        node.setIpv4("18.216.6.197");
        node.setPort("33445");
        node.setPublicKey("H8sqhRrQuJZ6iLtP2wanxt4LzdNrN2NNFnpPdq1uJ9n2");
        arrayList.add(node);

        node = new BootstrapNode();
        node.setIpv4("52.83.171.135");
        node.setPort("33445");
        node.setPublicKey("5tuHgK1Q4CYf4K5PutsEPK5E3Z7cbtEBdx7LwmdzqXHL");
        arrayList.add(node);

        setBootstrapNodes(arrayList);
    }
}
    
 
    
 
declare let carrierPlugin: any;

let callbacks = {};

let carrierInst;

function success(ret) {
    carrierInst = ret;
}

function error(ret) {
    // do something
}

carrierPlugin.createObject(success, error, null, callbacks);
    

Create a handler to receive status changes

A handler object will be provided to carrier, and several callbacks will be triggered there. From that handler you will be able to handle some of your app’s logic.

 
public class DefaultCarrierHandler extends AbstractCarrierHandler {
    @Override
    public void onConnection(Carrier carrier, ConnectionStatus status) {
        Logger.getGlobal().info("Carrier connection status: " + status);

        if(status == ConnectionStatus.Connected) {
            // Do something
        }
    }

    @Override
    public void onFriendRequest(Carrier carrier, 
                                String userId, 
                                UserInfo info, 
                                String hello) {
        Logger.getGlobal().info("Carrier received friend request. Peer UserId: " + userId);
        carrier.acceptFriend(userId);
    }

    @Override
    public void onFriendAdded(Carrier carrier, FriendInfo info) {
        Logger.getGlobal().info("Carrier friend added. Peer UserId: " + info.getUserId());
    }

    @Override
    public void onFriendConnection(Carrier carrier, 
                                   String friendId, 
                                   ConnectionStatus status) {
        Logger.getGlobal().info("Carrier friend connect. peer UserId: " + friendId);
        Logger.getGlobal().info("Friend status:" + status);

        if(status == ConnectionStatus.Connected) {
            // Do something
        } else {
            // Do something
        }
    }

    @Override
    public void onFriendMessage(Carrier carrier, String from, byte[] message) {
        Logger.getGlobal().info("Message from userId: " + from);
        Logger.getGlobal().info("Message: " + new String(message));
    }
}
  
 
    
 
declare let carrierPlugin: any;

let callbacks = {
    onConnection: connection_callback,
    onReady: ready_callback,
    onSelfInfoChanged: self_info_callback,
    onFriends: friends_list_callback,
    onFriendConnection: friend_connection_callback,
    onFriendInfoChanged: friend_info_callback,
    onFriendPresence: friend_presence_callback,
    onFriendRequest: friend_request_callback,
    onFriendAdded: friend_added_callback,
    onFriendRemoved: friend_removed_callback,
    onFriendMessage: message_callback,
    onFriendInviteRequest: invite_request_callback,
    onSessionRequest: session_request_callback,
}

function connection_callback(event) {
    switch (event.status) {
        case carrierPlugin.ConnectionStatus.CONNECTED:
            // do something
            break;

        case carrierPlugin.ConnectionStatus.DISCONNECTED:
            // do something
            break;

        default:
            // do something
    }
}

function ready_callback(event) {
    // do something
}

function self_info_callback(event) {
    // do something
}

function friends_list_callback(event) {
    // do something
}

function friend_connection_callback(event) {
    switch (event.status) {
        case carrierPlugin.ConnectionStatus.CONNECTED:
            // do something
            break;

        case carrierPlugin.ConnectionStatus.DISCONNECTED:
            // do something
            break;

        default:
            // do something
    }
}

function friend_info_callback(event) {
    // do something
}

function friend_presence_callback(event) {
    if (event.presence >= carrierPlugin.PresenceStatus.NONE &&
        event.presence <= carrierPlugin.PresenceStatus.BUSY) {
        // do something
    } else {
        // do something
    }
}

function friend_request_callback(event) {
    // do something
}

function friend_added_callback(event) {
    // do something
}

function friend_removed_callback(event) {
    // do something
}

function message_callback(event) {
    // do something
}

function invite_request_callback(event) {
    // do something
}

function session_request_callback(event) {
    // do something
}

let carrierInst;

function success(ret) {
    carrierInst = ret;
}

function error(ret) {
    // do something
}

carrierPlugin.createObject(success, error, null, callbacks);
    

Start Carrier

Now that we have options, and a handler, we can start carrier like this:

 
// Initial setup
Carrier.Options options = new DefaultCarrierOptions(context.getFilesDir().getAbsolutePath());
CarrierHandler handler = new DefaultCarrierHandler();

// Create or get an instance
Carrier.initializeInstance(options, handler);
Carrier carrier = Carrier.getInstance();

// Start the service
carrier.start(500); // Start carrier. Wait 500 milliseconds between each check of carrier status (polling)
    
 
    
 
carrierInst.start(null, null, 500);
    

Create a peer address

As a peer on carrier network, you can retrieve your carrier unique address using the following code:

 
String myPeerAddress = Carrier.getInstance().getAddress()
    
 
    
 
carrierInst.address;
    

This address can send me send to a friend (usually, through a QR code or a link) so he can add it into his own app to request to connect as a friend.

Add a friend

Carrier supports friends management. You can add a peer as a friend using its peer address. That address can be retrieved from your friend’s application context. This can be provided by the application through a QR code, for instance.

Note that all operations such as adding a friend or sending a message currently require both parties to be online.

 
Carrier.getInstance().addFriend(peerAddr, CARRIER_HELLO_AUTH);
    
 
    
 
carrierInst.addFriend(success, error, peerAddress, hello);
    

After requesting a peer address to become friend, that peer will receive your request in its DefaultCarrierHandler, inside onFriendRequest(). At that time, peer’s app can choose to accept or reject your invitation.

Accept an invitation to become friend

When a peer receives an invitation in onFriendRequest(), he can accept it like this:

 
    @Override
    public void onFriendRequest(Carrier carrier, 
                                String userId, 
                                UserInfo info, 
                                String hello) {
if (hello.equals(YOUR_UNIQUE_KEY_FOR_YOUR_APP) == false) {
    Logger.getGlobal().geterror("Ignore to accept friend, not expected.");
    return;
}
                                }
Carrier.getInstance().acceptFriend(userId);
    
 
    
 
carrierInst.acceptFriend(success, error, userId);
    

When the request is accepted, both parties receive the information in onFriendAdded().

Listen to friends activity

You can know when friends come online or offline listening to the onFriendConnection() callback:

 
@Override
public void onFriendConnection(Carrier carrier, String userId, ConnectionStatus status) {
    if(status == ConnectionStatus.Connected) {
        // Do something
    }
}
    
 
    
 
declare let carrierPlugin: any;

function friend_connection_callback(event) {
    switch (event.status) {
        case carrierPlugin.ConnectionStatus.CONNECTED:
            // do something
            break;

        case carrierPlugin.ConnectionStatus.DISCONNECTED:
            // do something
            break;

        default:
            // do something
    }
}
    

Send a message to a friend

Sending a message to a friend is as easy as this. Please note that only friends can receive messages to prevent spam.

 
Carrier.getInstance().sendFriendMessage(userId, message);
    
 
    
 
carrierInst.sendFriendMessage(success, error, userId, message);
    

Receive a message

Messages are received by the carrier handler:

 
@Override
public void onFriendMessage(Carrier carrier, String userId, String message) {
}
    
 
    
 
function message_callback(event) {
    // do something
}
    

Stop Carrier

 
Carrier carrier = Carrier.getInstance();
carrier.kill();
    
 
    
 
carrierInst.destroy(null, null);