Try Live Demo

We are starting a series of blog posts that explains how to do WebRTC chat and file transfer with Ant Media Server. This is the first part which is about chat and text messaging using WebRTC.

In the early days of the Internet, the only real means of communication were texting and real-time video conferences were elements of science fiction, but now, thanks to the better bandwidth, protocols, and streaming servers as it is part of our everyday life.

images

But still, text messaging is not extinct and on contrary, people are sending more messages and pictures through popular chat applications than ever before. For many use cases, video streaming should be augmented with text messaging and sometimes with binary file transfer to make it more convenient and useful.

For example in E-Learning, sometimes it is better to send the questions or comments of students through text messages during a streamed lecture or the students should be able to send their homework or photos during a video conference. WebRTC Data Channels supported by Ant Media Server Enterprise Edition 2.0 allows all of these with low latency and in a secure way. Please check our previous blog post in the series to learn more about it and its use cases.

In this blog post, we will implement a simple demonstrative chat application between Android and Web platforms employing Ant Media Server’s easy-to-use WebRTC Data Channel APIs. This sample application will also be included in the Ant Media Server Enterprise Edition 2.0 SDKs to guide our customers and increase their productivity with customizable solutions to common problems.

WebRTC Data Channel Usage and Message Format

How to set up and use WebRTC Data Channels in our SDKs is described in the previous blog post. Here, we will focus more on the best practices when using Data Channels and demonstrate their capabilities with a multiplatform chat and image transfer application.

For communication between different clients, it is always better to send the text messages in a structured data format like XML or JSON. Here is a simple example JSON TextMessage object representing our text messages:

{ messageId:"uniqueId1", // unique id for each message
messageDate: 23414123235, // time and date as long unix time stamp
messageBody: "Hi"} // actual text message typed by the user

Having a unique id and date can be useful for functions like manipulating or deleting messages for all chat participants or sorting them. This model can be extended with more metadata like references to other messages, and the user or device id of the device, which sends the message, based on use cases.

Sending Text Messages

In Android, we send text messages using sendTextMessage method. It first gets the text from the user input as below.

public void sendTextMessage() {
  String messageToSend = messageInput.getText().toString();
  String messageToSendJson = Message.createJsonTextMessage(computeMessageId(), new Date(), messageToSend);
  final ByteBuffer buffer = ByteBuffer.wrap(messageToSendJson.getBytes(Charset.defaultCharset()));
  DataChannel.Buffer buf= new DataChannel.Buffer(buffer,false);
  webRTCClient.sendMessageViaDataChannel(buf);
}

Then creates a JSON TextMessage object with a unique id and current date and converts this String to a raw data ByteBuffer. Finally, it creates a non-binary DataChannel.Buffer object and attempts to send it through sendMessageViaDataChannel method of the active WebRTCClient.

After it is successfully sent, onMessageSent method of IDataChannelObserver Interface is called where you need to display it on the screen.

Similarly in Web SDK, we implemented a sendTextMessage method where we get the user message from the text Input and create JSON TextMessage object. Then we stringify it and then send it through active webRTCAdaptor.

function sendTextMessage() {
  var text = $("#dataTextbox").val();
  var dateObj = new Date();
  var dateTime = dateObj.getTime();
  var messageObject = { messageId:createId() , messageDate:dateTime, messageBody:text};
  sendText(JSON.stringify(messageObject));
  createNewMessage(text, dateObj.toLocaleTimeString(), true);
  $("#dataTextbox").val(""); 
}

After that, if everything is successful, we show it on the screen.

Receiving and Displaying Text Messages

In Android, the messages from another side of the Data Channel are received by onMessage(DataChannel.Buffer) method of IDataChannelObserver Interface. Below you can see how non-binary data are handled in this method:

public void onMessage(final DataChannel.Buffer buffer, String dataChannelLabel) {
  if (!buffer.binary) {
    ByteBuffer data = buffer.data;
    String strDataJson = new String(data.array(), StandardCharsets.UTF_8);
    final Message message = new TextMessage();
    message.parseJson(strDataJson);
    messageAdapter.add(message);
    // scroll the ListView to the last added element
    messagesView.setSelection(messagesView.getCount() - 1);
  }
}
WebRTC Chat Message UI in Android

WebRTC Chat Message UI in Android

These text messages are converted back to String from the raw data buffer and parsed to a TextMessage object using standard JSON parser of the Android. After that to display these messages on the screen, we used a standart ListView of the Android UI. We created a custom ListAdapter called MessageAdapter to manage our ListView for messages.

 public class MessageAdapter extends BaseAdapter { 

 List<Message> messages = new ArrayList<Message>(); 

 Context context;  

 int colorCodeForReceivedMessage; 

..

Inside the overridden getView method of the MessageAdapter, we create TextViews for messageBody and messageDate of the parsed message. We inflate different Android Layouts for the messages sent by us and the messages we received to display them accordingly.

public View getView(int i, View convertView, ViewGroup viewGroup) {
  Message message = messages.get(i);
  LayoutInflater messageInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
  TextView messageDate;
  if(message instanceof TextMessage) {
    TextView messageBody;
    TextMessage textMessage = (TextMessage) message;
    if (message.isBelongsToCurrentUser()) {
    // this message was sent by us
    convertView = messageInflater.inflate(R.layout.my_message, null);
    messageBody = convertView.findViewById(R.id.message_body);
    messageDate = convertView.findViewById(R.id.message_date);
    messageDate.setText(textMessage.getMessageDate());
    messageBody.setText(textMessage.getMessageBody());
  } else {
    // this message was sent by someone else
    convertView = messageInflater.inflate(R.layout.their_message, null);
    ...    
  }
}

To give message boxes in UI round borders, we created a drawable XML resource.

webMessageScreenshot

Screenshot of the Web Text Message UI

In the Web side, when a Data Channel message is received, the callback method of WebRTCAdaptor is fired with “data_received” signal. If it is a text message, here we parse the JSON String and create necessary HTML elements for this message to display it as a message box and add it to the HTML DOM using JQuery.


else if (info == "data_received") {
  var data = obj.event.data;
  if (data instanceof ArrayBuffer) {
    ...
  } else if (data instanceof Blob) {
    ...
  } else {
    var messageObj = JSON.parse(data);
    var dateObj = new Date(messageObj.messageDate); 
    createNewMessage(messageObj.messageBody, dateObj.toLocaleTimeString(), false);
  }
}

We used only JQuery for HTML DOM manipulation and Bootstrap for styling as libraries. Our goal was to keep it simple for demonstration purposes but depending on your use case, utilizing a framework like React and creating UI components for displaying messages can be more practical.

In this blog post, we implemented a simple but practical video chat application using Ant Media Server WebRTC Data Channels without using any complicated frameworks specialized for this purpose. WebRTC Data Channels makes building many more exciting projects possible and the full source code of this sample project will be included in our SDKs to guide our customers when implementing feature-rich, creative and amazing applications. In part 2, we will add a file transferring feature to the chat application.

WebRTC Data Channels will be available to our customers with our Web, Android and IOS SDKs in version 2.0. If you have any questions, please drop a line to contact@antmedia.io .

If you want to get our latest release 2.0, please visit us here and kindly request.

References:

1- Image Chat taken from: https://healthitsecurity.com/features/how-healthcare-secure-texting-messaging-impact-the-industry Source: ThinkStock


Burak Kekeç

Burak has been a Software Developer at Ant Media since its beginning in 2017. Overall he has 16 years of expertise in software development experience with C, C++, Java EE, and Android.