Node.js Express Project to Build Omegle Clone P2P WebRTC Random Text Chat Using Socket.io Rooms & Namespaces in Browser Using Javascript Full Project For Beginners

 

 

 

npm init -y

 

 

npm i express socket.io

 

 

 

server.js

 

 

// var emoji = require('emoji-parser');

var express = require("express"),
    faker = require("faker"),
    app = express(),
    http = require('http').Server(app),
    io = require('socket.io')(http),
    port = process.env.PORT || 3003,
    waiting_list=[],
    temp_partner,
    num_users=0;

app.use('/static',express.static(__dirname+"/static"));
// app.use('/emoji/images',express.static(__dirname+"/node_modules/emoji-parser/emoji/"));

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

// emoji.init().update();


io.on('connection', function(socket){

    num_users++;
    socket.partner=null;
    socket.username='anonymous-'+faker.name.firstName();
    socket.avatar=faker.internet.avatar();
    socket.emit("init",{username:socket.username,avatar:socket.avatar,my_id:socket.id});

    if(waiting_list.length>0){
        temp_partner=waiting_list[0];
        socket.partner=temp_partner;
        waiting_list.splice(0,1);
        socket.broadcast.to(temp_partner).emit("partner", {id:socket.id,username:socket.username,avatar:socket.avatar});
    }else{
        waiting_list.push(socket.id);
    }
    console.log("Active Users = "+num_users+",Waiting list size="+waiting_list.length);

    socket.on('chat message', function(data){
        // var msg = emoji.parse(data.msg, '/emoji/images');
        var msg=data.msg;
        var target=data.target;
        var source=socket.id;
        socket.broadcast.to(target).emit("chat message partner", msg);
        io.to(source).emit("chat message mine", msg);
    });

    socket.on('partner', function(packet){
        socket.partner=packet.target;
        socket.broadcast.to(socket.partner).emit("partner", packet.data);
    });

    socket.on('disconnect', function () {
        if(socket.partner!=null){
            socket.broadcast.to(socket.partner).emit("typing", false);
               socket.broadcast.to(socket.partner).emit("disconnecting now", 'Your Partner has disconnected . Refresh page to chat again');
        }
        else{
            waiting_list.splice(0,1);
        }
        num_users--;
        console.log("Active Users = "+num_users+",Waiting List="+waiting_list.length);
    });

    socket.on('typing',function (data) {
        socket.broadcast.to(socket.partner).emit("typing", data);
    })

});

http.listen(port, function(){
    console.log('listening on *:' + port);
});

 

 

index.html

 

 

<!doctype html>
<html>
<head>

    <title>Omegle Clone Random Text Chat</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
	<link rel="stylesheet" media="screen" href="static/css/bootstrap.min.css" />
	<link rel="stylesheet" media="screen" href="static/css/main.css" />
	<link rel="stylesheet" media="screen" href="static/css/lights.css" />
	<link rel="stylesheet" href="static/css/emojionearea.min.css">
	<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/emojione@3.1.2/extras/css/emojione.min.css"/>
	
</head>

<body>
	<canvas id="canvas"></canvas>
	<ul class="lightrope">
			<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
	</ul>
	<div id="bodyDiv">
		<br><br><br>
		<div class="row">
			<div class="col-xs-6 col-sm-12">
				<h1 class="text-center no-margin">Omegle Clone Random P2P WebRTC Text Chat</h1>
			</div>
			<div class="top-right col-xs-6 col-sm-12">
				<h3 class="text-center no-margin">Chat with someone random</h3>
			</div>
		</div>
		<div id = "outerdiv">
			<div id="partnerdiv" class="col-sm-2">
				<span id="partnerinfo">
					<div class="align-left">
						<h3>You're talking to:</h3>
						<br>
						<h3 id="partnername"></h3>
						<br>
					</div>
					<img id = "partnerimg" src="">
				</span>
			</div>
			<div id="mydiv" class="col-sm-2">
					<span id="myinfo">
						<div class="align-left">
							<h3>You are:</h3>
							<br>
							<h3 id="myname"></h3>
							<br>
						</div>
						<img id = "myimg" src="">
					</span>
				</div>
			<div id="messagediv">
				<div id = "messages"></div>
				<div id = "newMessage">
					<form id='msgform' onsubmit="return submitForm()">
						<input type="text" id="m" autocomplete="off" placeholder="Wait for partner to join"/>
						<button id="submitButton"> <i class="fa fa-send-o"></i></button>
						<label id="istyping">Partner is typing...</label>
					</form>
				</div>
			</div>
			
		</div>
	</div>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/emojione@3.1.2/lib/js/emojione.min.js"></script>
	<script src="static/js/main.js"></script>
	<script type="text/javascript" src="static/js/snow.js"></script>
    <script type="text/javascript" src="static/js/emojionearea.min.js"></script>
</body>

</html>

 

 

main.js

 

 

const FORM_INPUT_DISABLED_COLOR='#000000';//'#e0e2e5';
const FORM_INPUT_MSG_COLOR='#ffffff';//'#00ff00';
const FORM_INPUT_SEND_COLOR='#0000ff';//'#0000ff';
const MSG_MINE_COLOR='#af1d1d';
const MSG_PARTNER_COLOR='#c66e01';

const URL_PAGE = window.location.href;
if (URL_PAGE == 'http://www.cse.iitd.ac.in/devclub/omegle/'){
  var socket = io('http://www.cse.iitd.ac.in',{ path: '/devclub/omegle/socket.io'});
}
else{
  var socket = io();
}

var timeout;
var partner_id,partner_username,partner_avatar,my_id;
var audio = new Audio('static/sounds/notif.mp3');

$("#messages").scrollTop($("#messages")[0].scrollHeight);
$('#partnername').html(" ");
$('#partnerimg').attr("src"," ");
$('#m').css("pointer-events","none");
$('#m').css("background",FORM_INPUT_DISABLED_COLOR);
$('form button').css("pointer-events","none");
$('form button').css("background",FORM_INPUT_DISABLED_COLOR);
$('#messages').append('<div class="partner"> Merry Christmas from DevClub<br>Try refreshing if you are not connected to anyone within a minute.   </div>');

function timeoutFunction() {
    socket.emit('typing', false);
}

function isTyping(){
    socket.emit('typing',true);
    clearTimeout(timeout);
    timeout = setTimeout(timeoutFunction, 1000);        
}

socket.on('typing', function(data) {
    if (data) {
        $("#istyping").css("visibility","visible")      // call function to show typing
    } else {
        $("#istyping").css("visibility","hidden")       // call function to stop typing
    }
});

function submitForm(){
    var msg = $('#m').emojioneArea()[0].emojioneArea.getText().trim();
    if(msg!=''){
        socket.emit('chat message', {msg: msg, target: partner_id});
    }
    $('#m').val('');
    $('div.emojionearea-editor').text('');
    return false;
}

socket.on('init',function (data) {
    socket.username=data.username;
    socket.avatar=data.avatar;
    my_id = data.my_id;
    $('#myname').html(socket.username);
    $('#myimg').attr("src",socket.avatar);
});

socket.on('chat message mine',function(msg){
    var output_msg = emojione.shortnameToImage(msg);
    var newData = '<div class="me" style="display:none">'+output_msg+'</div>';
    $(newData).appendTo($('#messages')).slideDown(speed=200,callback = function(){
        $("#messages").scrollTop($("#messages")[0].scrollHeight);
    });
    $('#messages .me').css('background',MSG_MINE_COLOR);
});


socket.on('chat message partner', function (msg) {
    audio.play();
    var output_msg = emojione.shortnameToImage(msg);        
    var newData = '<div class="partner" style="display:none">'+output_msg+'</div>';
    $(newData).appendTo($('#messages')).slideDown(speed=200,callback = function(){
        $("#messages").scrollTop($("#messages")[0].scrollHeight);
    });
    $('#messages .partner').css('background',MSG_PARTNER_COLOR);

});

socket.on('disconnecting now', function (msg) {
    $('#messages').append('<div class="partner">'+msg+"</div>");
    $("#messages").scrollTop($("#messages")[0].scrollHeight);
    $('#partnername').html(" ");
    $('#partnerimg').attr("src"," ");
    $('#m').css("pointer-events","none");
    $('#m').css("background",FORM_INPUT_DISABLED_COLOR);
    $('form button').css("pointer-events","none");
    $('form button').css("background",FORM_INPUT_DISABLED_COLOR);
    $('#m').attr("placeholder","");
});

socket.on('partner', function (partner_data) {
    if(partner_id==null){
        $('#messages').append("<div>"+'Connected to '+partner_data.username+"</div>");
        $('#partnername').html(partner_data.username);
        $('#partnerimg').attr("src",partner_data.avatar);
        $('#m').css("pointer-events","auto");
        $('#m').css("background",FORM_INPUT_MSG_COLOR);
        $('form button').css("pointer-events","auto");
        $('form button').css("background",FORM_INPUT_SEND_COLOR);
        partner_id = partner_data.id;
        partner_username=partner_data.username;
        partner_avatar=partner_data.avatar;
        $('#m').attr("placeholder","Type to send a message");
        $('div.emojionearea-editor').attr("placeholder","Type to send a message");
        socket.emit('partner',{target:partner_id,
            data:{id:socket.id,
                username:socket.username,
                avatar:socket.avatar}});
    }
});

$(document).ready(function() {        
    $("#m").emojioneArea({
        saveEmojisAs: 'shortname',
        events: {
            keyup: function(editor, event) {
                if (event.which == 13) {
                    $('form').submit();
                } else {
                    isTyping();
                }
            }
        }
    });
});

 

 

DOWNLOAD FULL SOURCE CODE

 

 

Leave a Reply