|
Router API: Group communication
|
The original goal of PeerDeviceNet is to enable communication among
a group of mobile/P2P devices. A natural choice could be multicast
groups, such as Java's
multicast API. However for mobile/P2P apps targeted by
PeerDeviceNet, it is not ideal solution for a number of reasons
including unreliable data transfers, and mostly important power
consumption. The recommended practice for multicast at mobile
devices is to turn on multicast temporarily for work such as service
discovery and then turn it off to save power.
So PeerDeviceNet builds simple multicast groups on top of TCP
connections.
- A communication group is identified by a string of any content
instead of by a class D address and UDP port.
- Groups are formed on top of TCP connections among peer
devices. These TCP connections be setup thru ConnectionService api
programmatically, or interactively thru some shared
ConnectionManager/Connectors which may implement specific
security and verification strategies.
- While ConnectionService is responsible for setting up
"physical" TCP connections among devices, GroupService is for
creating the logical communication structure of apps; an app can
participate in multiple communication groups.
The simple group communication API follows the intuitive Java
MulticastSocket api and can summarized as the following four
operations:
- joinGroup(grouId)
- leaveGroup(groupId)
- send(groupId,
message)
- recv(groupId,
message)
Apps using this
group communication api should add the following permission in its
AndroidManifest.xml:
<uses-permission
android:name="com.xconns.peerdevicenet.permission.REMOTE_MESSAGING"
/>
Many api methods will use the following class to describe peer
devices:
class DeviceInfo {
public String name;
public String addr;
public String port;
......
}
Correspondingly, use the following keys to pack the data inside a
message bundle:
"PEER_NAME", "PEER_ADDR", "PEER_PORT".
Group communication is implemented as an android service running
in a background process, which will cover the following features:
- group membership management: join/leave app specific
communication groups and detect peers’s join/leave.
- broadcast messages to all devices in groups, or send to a
specific device; receive messages from groups.
PeerDeviceNet provides three kinds of asynchronous API to support
group communications:
- Intents api
Apps can send startService() intents
to join / leave groups and send messages with the following action
names:
- ACTION_JOIN_GROUP = "com.xconns.peerdevicenet.JOIN_GROUP"
- ACTION_LEAVE_GROUP = "com.xconns.peerdevicenet.LEAVE_GROUP"
- ACTION_SEND_MSG = "com.xconns.peerdevicenet.SEND_MSG"
Apps can receive messages and group membership change events using
a broadcast receiver with filters of following action names:
- ACTION_RECV_MSG = "com.xconns.peerdevicenet.RECV_MSG"
- ACTION_PEER_JOIN = "com.xconns.peerdevicenet.PEER_JOIN"
- ACTION_PEER_LEAVE = "com.xconns.peerdevicenet.PEER_LEAVE"
- ACTION_SELF_JOIN = "com.xconns.peerdevicenet.SELF_JOIN"
- ACTION_SELF_LEAVE = "com.xconns.peerdevicenet.SELF_LEAVE"
Message related data are packaged as intent "extras" using the
following keys:
- "GROUP_ID": a string to identify the group
- "MSG_ID": an app specific message id (optional)
- "MSG_DATA": app message data, normally a byte[] array.
- "PEER_NAME", "PEER_ADDR", "PEER_PORT": destination/source
device info.
Please check this
Chat
app for using intent api.
- IDL api
The IDL(aidl) interfaces related to
group communication are defined in two files:
Apps using aidl api will bind to the following named service:
ACTION_GROUP_SERVICE =
"com.xconns.peerdevicenet.GroupService"
This service will expose the following methods to join/leave
groups and send messages:
IRouterGroupService {
//join a group named by "groupId"and
attach callback handler "h"
oneway void joinGroup(String groupId, in
DeviceInfo[] peers, in IRouterGroupHandler h);
//leave group identified by "groupId"
oneway void leaveGroup(String groupId, in
IRouterGroupHandler h);
//send message: if "dest" is not null,
it is only sent to device "dest"; otherwise it is broadcast to
all peers in group
oneway void send(String groupId, in
DeviceInfo dest, in byte[] msg);
//request for all peers inside group
"groupId"
oneway void getPeerDevices(String
groupId);
}
When joining group, apps will register handler object with methods
to receive messages from group and handle group membership change
events.
IRouterGroupHandler {
//receive a message from "src"
oneway void onReceive(in DeviceInfo src,
in byte[] msg);
//a new device join the group
oneway void onPeerJoin(in DeviceInfo
device);
//a device just left group
oneway void onPeerLeave(in DeviceInfo
device);
//i just finished joining a group,
return with all peer devices in this group
oneway void onSelfJoin(in DeviceInfo[]
devices);
//i just finished leaving a group
oneway void onSelfLeave();
//results of calling getPeerDevices:
return all devices in this group
oneway void onGetPeerDevices(in
DeviceInfo[] devices);
//something wrong during group
communication
oneway void onError(in String errInfo);
}
The recommended practice of accessing GroupService aidl interface
is by using
RouterGroupClient
which also handle some common book-keeping for you. Please check
out
github
sample project for sample of using RouterGroupClient helper
class.
Please check this
Chat
app for using IDL interfaces.
- Messenger api
Apps using Android standard messaging
pattern "Messenger" will bind to the following named service:
ACTION_MESSENGER_SERVICE =
"com.xconns.peerdevicenet.Messenger"
Once bound, a messenger will be
returned which can be used to send Message objects with the
following message ids:
public final static int JOIN_GROUP =
-10400;
public final static int LEAVE_GROUP = -10401;
public final static int SEND_MSG = -10500;
When joining group, apps will register
a callback messenger to receive remote messages and group
membership change events with the following message ids:
public final static int RECV_MSG =
-10510;
public final static int SELF_JOIN = -10410;
public final static int PEER_JOIN = -10411;
public final static int SELF_LEAVE = -10412;
public final static int PEER_LEAVE = -10413;
App message data are packaged as a
bundle using the same key names as Intent api.
Please check this Chat
app for using messenger api.
The complete source code project for
Chat apps is available from here.
The built app can be installed from
Google play to try out.