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, we already made a janus Object using janus.js and attach videoroom plugin to it in a previous blog. We can attach multiple handlers to that janus instance. Hence we can attach textroom plugin to it and implement the 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 is completed. instead this doesn't work.

How to send messages

We can send messages privately to participants or public message for all of the participants 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 you wish.