React Native Video Calling App – Part 5

Welcome to the tutorial React Native Video Calling App Part 5. In last tutorial we coded our app for one client to make call to another client. In this part of tutorial we will modify our code so that users can receive or reject calls. So, lets begin our journey .

Our client code code after modification looks like this :

<!DOCTYPE html>
<html>
    <head>
        <title>Web Client</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>
    <div id="loginContainer">
     <input id="login" value="userA">
     <button onclick="user_login();">Enter Username</button>
   </div>
     <div id="callerIDContainer">
          <input id="callerID" value="userA">
          <button onclick="call_user();">Call User</button>
     </div>
    </body>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io();
        let username;
        let busy = false;
        var incallwith = "";

    function user_login(){
            var login = document.getElementById('login').value;
            username = login;
      socket.send({
                     type: "login",
                     name: username
                 })
    }
        function call_user(){
            var callerID = document.getElementById('callerID').value;
          if (callerID == "") {
            alert('Please enter caller ID');
          } else {
                //const roomid = username+"-"+callerID;
                //join(roomid);
            var callerIDContainer = document.getElementById('callerIDContainer');
            callerIDContainer.parentElement.removeChild(callerIDContainer);
                busy = true;
                incallwith = callerID
                socket.send({
                 type: "call_user",
                 name: callerID,
                         callername: username
              })
          }
        }
        function onAnswer(data){
        if(busy == false){
            busy = true
            incallwith = data.callername
            var res = confirm(data.callername+" is calling you");
            if(res == true){
                console.log("call accepted");
                // code
                socket.send({
                     type: "call_accepted",
                     callername: data.callername,
                     from: username
                    })

                    }else{
                   console.log("call rejected");
                     socket.send({
                            type: "call_rejected",
                            callername: data.callername,
                            from: username
                     })
                     busy = false
                     incallwith = ""
                 }
             }else{
                 console.log("call busy");

             }
            }
         function onResponse(data){
                switch(data.response){
                    case "accepted":
                    incallwith = data.responsefrom;
                    console.log("Call accepted by :"+ data.responsefrom);
                    // code
                    break;
                    case "rejected":
                    console.log("Call rejected by :"+ data.responsefrom);
                    busy = false;
                    incallwith = ""
                    break;
                    case "busy":
                    console.log(data.responsefrom+" call busy");
                    busy = false;
                    incallwith = ""
                    break;
                    default:
                    console.log(data.responsefrom+" is offline");
                    busy = false;
                    incallwith = ""
                }

            }

    socket.on('connect', function(data) {
          console.log('connect');
        });
        //when a user logs in
        function onLogin(data) {

             if (data.success === false) {
                    alert("oops...try a different username");
             } else {
                 var loginContainer = document.getElementById('loginContainer');
                 loginContainer.parentElement.removeChild(loginContainer);
                 username = data.username;
                 console.log("Login Successfull");
                 console.log("logged in as :"+username);
                 console.log(data.userlist);
             }
        }
        socket.on('roommessage', function(message){
            var data = message;

            switch(data.type) {
                 case "login":
                        console.log("New user : "+data.username);
                        break;
                 case "disconnect":
                   console.log("User disconnected : "+data.username);
                 break;
                default:
                    break;
            }
        })
    socket.on('message', function(message){
            var data = message;

            switch(data.type) {
                 case "login":
                        onLogin(data);
                        break;
                case "answer":
                      console.log("getting called");
                        onAnswer(data);
                        break;
                case "call_response":
                      onResponse(data);
                      break;
                default:
                    break;
            }
    })
  </script>
  </html>

In the above code, once the user receives the call, the control passes to function ‘onAnswer’. Now,  if the user receives the call we send a message of type ‘call_accepted’ to the server. If user rejects the call, we send a message of type ‘call_rejected’ to the server.

When server passes the accept or reject message to another client, we handle it in ‘onResponse’ function of switch case ‘call_response’ .

Now lets see whats happening in ‘onResponse’ function. If call has been accepted by user, then, code in switch case ‘accepted’ of ‘onResponse’ method is executed. Here we assign the incallwith variable with the username of user to whom call has been made and log a call accepted message. When call is rejected we simply log call rejected message and reset the busy variable to false and incallwith to empty string. Thats all we need to do in the client side.

Below lets check the server side code. Below is the modified code of server side :

var express = require('express');
var app = express();
var open = require('open');
var serverPort = (4443);
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io')(server);
var sockets = {};
var users = {};
function sendTo(connection, message) {
   connection.send(message);
}

app.get('/', function(req, res){
  console.log('get /');
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log("user connected");

  socket.on('disconnect', function () {
    console.log("user disconnected");
    if(socket.name){
      socket.broadcast.to("chatroom").emit('roommessage',{ type: "disconnect", username: socket.name})
      delete sockets[socket.name];
      delete users[socket.name];
    }

  })

  socket.on('message', function(message){

    var data = message;

    switch (data.type) {

    case "login":
      console.log("User logged", data.name);

      //if anyone is logged in with this username then refuse
      if(sockets[data.name]) {
         sendTo(socket, {
            type: "login",
            success: false
         });
      } else {
         //save user connection on the server
         var templist = users;
         sockets[data.name] = socket;
         socket.name = data.name;
         sendTo(socket, {
            type: "login",
            success: true,
            username: data.name,
            userlist: templist
         });
         socket.broadcast.to("chatroom").emit('roommessage',{ type: "login", username: data.name})
         socket.join("chatroom");
         users[data.name] = socket.id
      }

      break;
      case "call_user":
      // chek if user exist
        if(sockets[data.name]){
          console.log("user called");
          console.log(data.name);
          console.log(data.callername);
        sendTo(sockets[data.name], {
           type: "answer",
           callername: data.callername
        });
      }else{
        sendTo(socket, {
           type: "call_response",
           response: "offline"
        });
      }
      break;
      case "call_accepted":
      sendTo(sockets[data.callername], {
         type: "call_response",
         response: "accepted",
         responsefrom : data.from

      });
      break;
      case "call_rejected":
      sendTo(sockets[data.callername], {
         type: "call_response",
         response: "rejected",
         responsefrom : data.from
      });
      break;
      default:
      sendTo(socket, {
         type: "error",
         message: "Command not found: " + data.type
      });
      break;
}

  })
})

server.listen(serverPort, function(){
   console.log('server up and running at %s port', serverPort);
 });

In the above code, we have 2 new switch cases below ‘call_user’ switch case i.e. ‘call_accepted’ and ‘call_rejected’. What is happening in these two switch cases are quite simple. In ‘call_accepted’ case we are sending a message of type ‘call_response’ to calling user with response property set to ‘call_accepted’. Similarly, in ‘call_rejected’ case we are sending a message of type ‘call_response’ to calling user with response property set to ‘call_rejected’. Thats all we need to do in the server side.

So, now our users can make call to each other as well as accept it or reject it. In next part of tutorial we will check if the users call is busy, and, will also check the condition if there is sudden call drop of any user. Make sure you subscribe to our newsletter to keep yourself upto date about latest in react native world.

Video Tutorial

Demo

 

 

One thought on “React Native Video Calling App – Part 5”

Comments are closed.