Janus
Implement chat room in video conference application using janus textroom plugin
July 13, 2021
1 min

Implement chat room in video conference application using janus textroom plugin

What is janus?

As described by its creator meetecho, janus is a general purpose WebRTC endpoint that browsers can interact with, and different modules can determine what should be done with the media. You can do, text messaging, video conferencing, streaming and more other things with janus. Also if there is no such module to do stuff what you are looking, you can expand janus by yourself.

What is janus TextRoom plugin?

As per the meetecho, This is a plugin implementing a DataChannel only text room. As such, it does NOT support or negotiate audio or video, but only data channels, in order to provide text broadcasting features. The plugin allows users to join multiple text-only rooms via a single PeerConnection. Users can send messages either to a room in general (broadcasting), or to individual users (whispers). This plugin can be used within the context of any application that needs real-time text broadcasting (e.g., chatrooms, but not only).

Implement chat room functionality

In order to implement video conference, already make janus Object using janus.js and attach videoroom plugin to it. We can attach multiple handlers to that janus instance. So that we can attach textroom plugin to it and implement chat room in our video conference.

janusRoom.attach(
    {
    plugin:  "janus.plugin.textroom",
    opaqueId:  opaqueId,
    success:  function(pluginHandle) {
        textroom = pluginHandle;
        Janus.log("Plugin attached! (" + textroom.getPlugin() + ", id=" +                       textroom.getId() + ")");
        var  body = { request:  "setup" };
        Janus.debug("Sending message:", body);
        textroom.send({ message:  body });
        // Setup the DataChannel
    },
    error:  function(error) {
        console.error(" -- Error attaching plugin...", error);
    },
    iceState:  function(state) {
        Janus.log("ICE state changed to " + state);
    },
    mediaState:  function(medium, on) {
        Janus.log("Janus " + (on ? "started" : "stopped") + " receiving our "   + medium); 
    },
    webrtcState:  function(on) {
        Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
    },
    onmessage:  function(msg, jsep) {
        Janus.debug(" ::: Got a message :::", msg, jsep);
        if(msg["error"]) {    
        }
        if(jsep) {
            // Answer
            textroom.createAnswer({
                jsep:  jsep,
                media: { audio:  false, video:  false, data:  true }, // We only use datachannels
                success:  function(jsep) {
                    Janus.debug("Got SDP!", jsep);
                    var  body = { request:  "ack" };
                    textroom.send({ message:  body, jsep:  jsep,
                        success: () => {    
                            let  reg = store.getState().conference.name
                            const  register = { textroom:  "join", room:  myroom, transaction:  randomString(12), username:  reg, display:  reg }; 
                            textroom.data({
                                text:  JSON.stringify(register),
                                error:  function(reason) {
                                    console.log(reason)
                                }

                    });

                }

            });

       },
            error:  function(error) {
                Janus.error("WebRTC error:", error);
            }
        });
    }
},
    ondataopen:  function(data) {
        Janus.log("The DataChannel is available!");
        // Prompt for a display name to join the default room
    },
    ondata:  function(data) {
        Janus.debug("We got data from the DataChannel!", data);
        var  json = JSON.parse(data)
        var  transaction = json["transaction"];
        if(transactions[transaction]) {
            // Someone was waiting for this
            transactions[transaction](json);
            delete  transactions[transaction];
            return;
        }
        var  what = json["textroom"];
        if(what === "message") {
            // Incoming message: public or private?
            var  msg = json["text"];
            msg = msg.replace(new  RegExp('<', 'g'), '&lt');
            msg = msg.replace(new  RegExp('>', 'g'), '&gt');
            var  from = json["from"];
            // var dateString = getDateString(json["date"]);
            var  whisper = json["whisper"];
            if(whisper === true) {
                // Private message
                document.querySelector('#chatroom').append('<p>['+'-->'+'] <b>[whisper from ' + participants[from] + ']</b> ' + msg);
            } else {
                // Public message
                document.querySelector('#chatroom').append(from + ' : ' + msg);
            }
        } else  if(what === "join") {
            // Somebody joined
            var  username = json["username"];
            var  display = json["display"];
            participants[username] = display ? display : username;
            }
        },
    });
},
error:  function(error) {
    Janus.error(error);
    alert(error);
},
destroyed:  function() {
    console.log('destroyed');
}

Note that we have to join the textroom after the setup of data channel completed. instead this doesn’t work.

How to send messages

We can send messages privately to participants or public message for all of the participant in the room.

  • send public messages

        export  function  sendData(data) {
            if(data === "") {
                alert('Insert a message to send on the DataChannel');
                return;
            }
        let  message = {
            textroom:  "message",
            transaction:  randomString(12),
            room:  myroom,
            text:  data,
        };  
        textroom.data({
            text:  JSON.stringify(message),
            error:  function(reason) {
            console.log(reason)
            },
            success:  function() { }
        });
    }
    
  • send private messages

    function sendPrivateMsg(username) {
        var display = participants[username];
            if(!display)
                return;
                bootbox.prompt("Private message to " + display, function(result) {
                if(result && result !== "") {
                    var message = {
                        textroom: "message",
                        transaction: randomString(12),
                        room: myroom,
                        to: username,
                        text: result
                    };
                    textroom.data({
                        text: JSON.stringify(message),
                        error: function(reason) { bootbox.alert(reason); },
                        success: function() { }
                    });
                }
            });
        return;
    }
    

Now you can style your chat room as your wish.


Tags

webrtcjanusubuntutextroomconferencemultiple handlersmultiple plugins

Related Posts

Janus
How to install Janus Gateway in Ubuntu Server 18.04
July 15, 2021
1 min