Host signalling server on heroku - node.js

I have built a signalling server using webrtc, nodejs, web-socket.
I am able to run the server locally but i want to host the server on heroku.
O have looked all over the internet but i cannot find anything relevant.
How can i host this server on Heroku?
Here is my code
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({port: 9090});
var users = {};
wss.on('connection', function(connection) {
console.log("User connected");
//when server gets a message from a connected user
connection.on('message', function(message) {
var data;
//accepting only JSON messages
try {
data = JSON.parse(message);
} catch (e) {
console.log("Invalid JSON");
data = {};
}
//switching type of the user message
switch (data.type) {
//when a user tries to login
case "login":
console.log("User logged", data.name);
//if anyone is logged in with this username then refuse
if(users[data.name]) {
sendTo(connection, {
type: "login",
success: false
});
} else {
//save user connection on the server
users[data.name] = connection;
connection.name = data.name;
sendTo(connection, {
type: "login",
success: true
});
}
break;
case "offer":
//for ex. UserA wants to call UserB
console.log("Sending offer to: ", data.name);
//if UserB exists then send him offer details
var conn = users[data.name];
if(conn != null) {
//setting that UserA connected with UserB
connection.otherName = data.name;
sendTo(conn, {
type: "offer",
offer: data.offer,
name: connection.name
});
}
break;
case "answer":
console.log("Sending answer to: ", data.name);
//for ex. UserB answers UserA
var conn = users[data.name];
if(conn != null) {
connection.otherName = data.name;
sendTo(conn, {
type: "answer",
answer: data.answer
});
}
break;
case "candidate":
console.log("Sending candidate to:",data.name);
var conn = users[data.name];
if(conn != null) {
sendTo(conn, {
type: "candidate",
candidate: data.candidate
});
}
break;
case "leave":
console.log("Disconnecting from", data.name);
var conn = users[data.name];
conn.otherName = null;
//notify the other user so he can disconnect his peer connection
if(conn != null) {
sendTo(conn, {
type: "leave"
});
}
break;
default:
sendTo(connection, {
type: "error",
message: "Command not found: " + data.type
});
break;
}
});
//when user exits, for example closes a browser window
//this may help if we are still in "offer","answer" or "candidate" state
connection.on("close", function() {
if(connection.name) {
delete users[connection.name];
if(connection.otherName) {
console.log("Disconnecting from ", connection.otherName);
var conn = users[connection.otherName];
conn.otherName = null;
if(conn != null) {
sendTo(conn, {
type: "leave"
});
}
}
}
});
connection.send("Hello world");
});
function sendTo(connection, message) {
connection.send(JSON.stringify(message));
}
Above is the code sample of server.js file.
Any help will be appreciated?

Here it is:
Step1: Push you code on github.
Before pushing make changes in your package.json.
Package.json is really important file to run your server on any cloud. Mainly start script, dependencies and node version is important.
Also in your code use process.env.PORT instead of any hard coded port number.
Step2: Create a heroku project through cli.
Now push you branch on heroku.
I know this is pretty brief steps. But I can help you more. If you are able to do it then good, otherwise I can help you in detail.

Related

WebRTC Call throwing a error during hangup

I am implementing a peer-2-peer call with WebRTC but I have encountered an error when leaving the call.
The connection is gone through but when I leave I get an error
The error is saying
connect.otherUser = null;
^
TypeError: Cannot set property 'otherUser' of undefined
This is the server.js
var webSocketServ = require('ws').Server;
var wss = new webSocketServ({
port: 9090
})
var users = {};
var otherUser;
wss.on('connection', function (conn) {
console.log("User connected");
conn.on('message', function (message) {
var data;
try {
data = JSON.parse(message);
} catch (e) {
console.log("Invalid JSON");
data = {};
}
switch (data.type) {
case "login":
if (users[data.name]) {
sendToOtherUser(conn, {
type: "login",
success: false
})
} else {
users[data.name] = conn;
conn.name = data.name
sendToOtherUser(conn, {
type: "login",
success: true
})
}
break;
case "offer":
var connect = users[data.name];
if (connect != null) {
conn.otherUser = data.name;
sendToOtherUser(connect, {
type: "offer",
offer: data.offer,
name: conn.name
})
}
break;
case "answer":
var connect = users[data.name];
if (connect != null) {
conn.otherUser = data.name
sendToOtherUser(connect, {
type: "answer",
answer: data.answer
})
}
break
case "candidate":
var connect = users[data.name];
if (connect != null) {
sendToOtherUser(connect, {
type: "candidate",
candidate: data.candidate
})
}
break;
case "reject":
var connect = users[data.name];
if (connect != null) {
sendToOtherUser(connect, {
type: "reject",
name: conn.name
})
}
break;
case "accept":
var connect = users[data.name];
if (connect != null) {
sendToOtherUser(connect, {
type: "accept",
name: conn.name
})
}
break;
case "leave":
var connect = users[data.name];
connect.otherUser = null;
if (connect != null) {
sendToOtherUser(connect, {
type: "leave"
})
}
break;
default:
sendToOtherUser(conn, {
type: "error",
message: "Command not found: " + data.type
});
break;
}
})
conn.on('close', function () {
console.log('Connection closed');
if(conn.name){
delete users[conn.name];
if(conn.otherUser){
var connect = users[conn.otherUser];
conn.otherUser = null;
if(conn != null){
sendToOtherUser(connect, {
type:"leave"
});
}
}
}
})
conn.send("Hello World");
});
function sendToOtherUser(connection, message) {
connection.send(JSON.stringify(message))
}
Also var otherUser; is declared but its value is never read
I don't know why there is an error when leaving the call

Clear the client console in SSH2 for NodeJS?

I am building a command-line game that players will connect to over SSH. I have an SSH2 server script that responds to commands, but I would like to know if it is possible to clear the client console from the server?
I would like to have a cls/clear command that clears the console at a user's request, like the Unix command 'clear'.
Here is my code:
var fs = require('fs');
var crypto = require('crypto');
var inspect = require('util').inspect;
var ssh2 = require('ssh2');
var utils = ssh2.utils;
var allowedUser = Buffer.from('foo');
var allowedPassword = Buffer.from('bar');
var allowedPubKey = utils.parseKey(fs.readFileSync('public.key')); ;
new ssh2.Server({
hostKeys: [{
key: fs.readFileSync('private.key'),
passphrase: '<private key passphrase>'
}
]
}, function (client) {
console.log('Client connected!');
client.on('authentication', function (ctx) {
var user = Buffer.from(ctx.username);
if (user.length !== allowedUser.length
|| !crypto.timingSafeEqual(user, allowedUser)) {
return ctx.reject();
}
switch (ctx.method) {
case 'password':
var password = Buffer.from(ctx.password);
if (password.length !== allowedPassword.length
|| !crypto.timingSafeEqual(password, allowedPassword)) {
return ctx.reject(['password'],false);
}
break;
default:
return ctx.reject(['password'],false);
}
ctx.accept();
}).on('ready', function () {
console.log('Client authenticated!');
client.once('session', function (accept, reject) {
var session = accept();
session.on('shell', (accept, reject) => {
var stream = accept();
stream.write('Welcome to EnLore!\n\r');
stream.on('data', data => {
var args = data.toString().replace("\n","").split(" ");
if (args[0] == '\r') return;
switch(args[0]) {
case 'exit':
stream.exit(0);
stream.end();
stream = undefined;
break;
case 'echo':
stream.write(args[1]);
break;
case 'clear':
// -------------- CLEAR CONSOLE HERE --------------
break;
default:
stream.write('Unknown command');
break;
}
stream.write('\n\r');
});
});
});
}).on('end', function () {
console.log('Client disconnected');
});
}).listen(8080, '0.0.0.0', function () {
console.log('Listening on port ' + this.address().port);
});
EDIT:
I have found that writing \f to the stream will clear the current window, however, it only appends to the console, rather than clearing it

SQL select all statement in a node.js application returns a tedious deprecated error

So I went to the Microsoft documentation for node.js and trying to connect to a database and I went through step by step, installed tedious and when I try to run my code it's throwing an error saying:
tedious deprecated In the next major version of tedious, creating a new Connection instance will no longer establish a connection to the server automatically. Please use the new connect helper function or call the .connect method on the newly created Connection object to silence this message. internal\process\task_queues.js:79:11.
Does anyone know what this means?
CODE:
const Discord = require('discord.js');
const bot = new Discord.Client();
const token = 'HIDDEN';
bot.on('ready', () => {
console.log('This bot is online!');
var Connection = require('tedious').Connection;
var config = {
server: '', //update me
authentication: {
type: 'default',
options: {
userName: '', //update me
password: '' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: '' //update me
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
if(!err)
{
console.log("Connected");
executeStatement();
}
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
function executeStatement() {
request = new Request("SELECT * from tblCustomer;", function(err) {
if (err) {
console.log(err);}
});
var result = "";
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
result+= column.value + " ";
}
});
console.log(result);
result ="";
});
request.on('done', function(rowCount, more) {
console.log(rowCount + ' rows returned');
});
connection.execSql(request);
}
})
bot.login(token);

Invalid channel name - What could be causing this?

I am working on a site that will have a chatbox on it, basically it has a bunch of channels for different languages as well a channel for moderators and a channel for announcements.
I am getting an error [join] invalid channel name and since i'm so new with coding/developing I thought i'd share my code in hopes someone here can tell me where I messed something up.
CHAT.JS
var assert = require('assert');
var CBuffer = require('CBuffer');
var events = require('events');
var util = require('util');
var _ = require('lodash');
var debug = require('debug')('app:chat');
var db = require('./database');
var lib = require('./lib');
//Mute users by ip/username and store muted users in the database
var CHAT_HISTORY_SIZE = 100;
var SPECIAL_CHANNELS = {
all: {
desc: 'Channel where all messages are broadcasted, read only',
writable: false,
modsOnly: false
},
moderators: {
desc: 'Channel for moderators only, they are joinedds',
writable: true,
modsOnly: true
}
//This is the behaviour for all the other channels:
//defaultProps: {
// desc: '',
// writable: true,
// modsOnly: false
//}
};
// There is a mods channel for every channel
// The mods are joined to a channel called mod:channelName
function Chat(io) {
var self = this;
self.io = io;
// Number of connected clients
self.clientCount = 0;
/*
Collection of muted users.
key: Username
value: Object with the following fields
time: Date object when the user was muted
moderator: The username of the moderator that muted the user
timespec: Initial (nominal diff) time the user has been muted
end: Until when the user is muted
shadow: If the mute is a shadow mute
*/
self.muted = {};
io.on('connection', onConnection);
function onConnection(socket) { //socket.user is attached on the login middleware
debug('socket connection event received');
//Attach disconnect handler
socket.on('disconnect', function() {
--self.clientCount;
console.log('Client disconnect, left: ', self.clientCount);
debug('client disconnect');
});
//Join to a Room
socket.on('join', function(channelName) {
debug('join event received from user %s', socket.user ? socket.user.username : '~guest~');
self.join(socket, channelName);
});
//Register the message event
socket.on('say', function(message, isBot, customChannelName) {
self.onSay(socket, message, isBot, customChannelName);
});
++self.clientCount;
console.log('Client joined: ', self.clientCount, ' - ', socket.user ? socket.user.username : '~guest~'); //TODO: Add ip address
}
events.EventEmitter.call(self); //Call event emitter 'constructor' function
}
util.inherits(Chat, events.EventEmitter);
Chat.prototype.join = function(socket, channelName) {
var self = this;
var moderator = socket.user && socket.user.moderator;
//Check channelName variable and avoid users to join the mods channel
**if(isChannelNameInvalid(channelName) || isChannelNameModsOnly(channelName))
return sendError(socket, '[join] Invalid channel name');**
//Check if the channel is moderators only
if(SPECIAL_CHANNELS.hasOwnProperty(channelName))
if(SPECIAL_CHANNELS[channelName].modsOnly && !moderator)
return sendError(socket, '[join] This channel is moderators only');
//Check if the user was joined to another room before, if it was leave that room
if(socket.currentChannel)
socket.leave(socket.currentChannel);
//If mod leave the mods channel for this channel
if(socket.modCurrentChannel)
socket.leave(socket.modCurrentChannel);
//Save the name of the current room in the socket, this can also be used to check if the user is joined into a channel
socket.currentChannel = channelName;
//Get user history of a room and send it to the user
self.getHistory(channelName, function(err, history) {
//If we couldn't reach the history send an empty history to the user
if(err) {
history = [];
}
var res = {
history: history,
username: socket.user ? socket.user.username : null,
channel: channelName,
moderator: moderator
};
//Actually join the socket.io room
socket.join(channelName);
//If the user is mod and is not on the mods channel join him to the channel mod:channelName
if(moderator && channelName !== 'moderators') {
var chan = 'mod:'+channelName;
socket.join(chan);
socket.modCurrentChannel = chan;
}
//Return join info to the user
socket.emit('join', res);
});
};
Chat.prototype.onSay = function(socket, message, isBot, customChannelName) {
if (!socket.user)
return sendError(socket, '[say] you must be logged in to chat');
if (!socket.currentChannel)
return sendError(socket, '[say] you must be joined before you can chat');
//Check if the message is for a custom channel
var channelName;
if(customChannelName)
if(isChannelNameInvalid(customChannelName))
return sendError(socket, '[say] invalid channel name');
else
channelName = customChannelName;
else
channelName = socket.currentChannel;
//Check if the message is for a non writable channel ('all')
if(SPECIAL_CHANNELS.hasOwnProperty(channelName) && !SPECIAL_CHANNELS[channelName].writable)
return sendErrorChat(socket, 'The all channel is read only');
//Message validation
message = message.trim();
if (typeof message !== 'string')
return sendError(socket, '[say] no message');
if (message.length == 0 || message.length > 500)
return sendError(socket, '[say] invalid message size');
var cmdReg = /^\/([a-zA-z]*)\s*(.*)$/;
var cmdMatch = message.match(cmdReg);
if (cmdMatch) //If the message is a command try to execute it
this.doChatCommand(socket.user, cmdMatch, channelName, socket);
else //If not broadcast the message
this.say(socket, socket.user, message, channelName, isBot);
};
Chat.prototype.doChatCommand = function(user, cmdMatch, channelName, socket) {
var self = this;
var cmd = cmdMatch[1];
var rest = cmdMatch[2];
switch (cmd) {
case 'shutdown':
return sendErrorChat(socket, '[shutdown] deprecated feature boss');
case 'mute':
case 'shadowmute':
if (user.moderator) {
var muteReg = /^\s*([a-zA-Z0-9_\-]+)\s*([1-9]\d*[dhms])?\s*$/;
var muteMatch = rest.match(muteReg);
if (!muteMatch)
return sendErrorChat(socket, 'Usage: /mute <user> [time]');
var username = muteMatch[1];
var timespec = muteMatch[2] ? muteMatch[2] : "30m";
var shadow = cmd === 'shadowmute';
self.mute(shadow, user, username, timespec, channelName,
function (err) {
if (err)
return sendErrorChat(socket, err);
});
} else {
return sendErrorChat(socket, '[mute] Not a moderator.');
}
break;
case 'unmute':
if (user.moderator) {
var unmuteReg = /^\s*([a-zA-Z0-9_\-]+)\s*$/;
var unmuteMatch = rest.match(unmuteReg);
if (!unmuteMatch)
return sendErrorChat(socket, 'Usage: /unmute <user>');
var username = unmuteMatch[1];
self.unmute(
user, username, channelName,
function (err) {
if (err) return sendErrorChat(socket, err);
});
}
break;
default:
sendErrorChat(socket, 'Unknown command ' + cmd);
break;
}
};
Chat.prototype.getHistory = function (channelName, callback) {
if(channelName === 'all')
db.getAllChatTable(CHAT_HISTORY_SIZE, fn);
else
db.getChatTable(CHAT_HISTORY_SIZE, channelName, fn);
function fn (err, history) {
if(err) {
console.error('[INTERNAL_ERROR] got error ', err, ' loading chat table');
return callback(err);
}
callback(null, history);
}
};
Chat.prototype.say = function(socket, user, message, channelName, isBot) {
var self = this;
var date = new Date();
isBot = !!isBot;
var msg = {
date: date,
type: 'say',
username: user.username,
role: user.userclass,
message: message,
bot: isBot,
channelName: channelName
};
//Check if the user is muted
if (lib.hasOwnProperty(self.muted, user.username)) {
var muted = self.muted[user.username];
if (muted.end < date) {
// User has been muted before, but enough time has passed.
delete self.muted[user.username];
} else if (muted.shadow) {
// User is shadow muted. Echo the message back to the
// user but don't broadcast.
self.sendMessageToUser(socket, msg);
return;
} else {
self.sendMessageToUser(socket, {
date: date,
type: 'info',
username: user.username,
role: user.userclass,
message: 'You\'re muted. ' + lib.printTimeString(muted.end - date) + ' remaining',
bot: false,
channelName: channelName
});
return;
}
}
self.sendMessageToChannel(channelName, msg, user.id);
};
/** Send a message to the user of this socket **/
Chat.prototype.sendMessageToUser = function(socket, msg) {
socket.emit('msg', msg);
};
/** Send a message to a channel and to the all channel and store it in the database **/
Chat.prototype.sendMessageToChannel = function(channelName, msg, userID) {
console.assert(msg.hasOwnProperty('bot') && msg.date, msg.hasOwnProperty('message') && msg.type);
this.io.to(channelName).emit('msg', msg);
this.io.to('all').emit('msg', msg);
this.saveChatMessage(userID, msg.message, channelName, msg.bot, msg.date);
};
Chat.prototype.saveChatMessage = function(userId, message, channelName, isBot, date) {
db.addChatMessage(userId, date, message, channelName, isBot, function(err) {
if(err)
console.error('[INTERNAL_ERROR] got error ', err, ' saving chat message of user id ', userId);
});
};
Chat.prototype.mute = function(shadow, moderatorUser, username, time, channelName, callback) {
var self = this;
var now = new Date();
var ms = lib.parseTimeString(time);
var end = new Date(Date.now() + ms);
// Query the db to make sure that the username exists.
db.getUserByName(username, function(err, userInfo) {
if (err) {
if(typeof err === 'string') //USERNAME_DOES_NOT_EXIST
callback(err);
else
console.error('[INTERNAL_ERROR] got error ', err, ' muting user ', userInfo.username);
return;
}
assert(userInfo);
// Overriding previous mutes.
self.muted[userInfo.username] = {
date: now,
moderator: moderatorUser.username,
timespec: time,
end: end,
shadow: shadow
};
var msg = {
date: now,
type: 'mute',
message: null,
moderator: moderatorUser.username,
username: userInfo.username,
timespec: time,
shadow: shadow,
bot: false
};
//If mute shadow inform only mods about it
if (shadow) {
self.io.to('moderators').emit('msg', msg);
self.io.to('mod:'+channelName).emit('msg', msg);
//If regular mute send mute message to the channel
} else {
self.io.to(channelName).emit('msg', msg);
self.io.to('moderators').emit('msg', msg);
}
callback(null);
});
};
Chat.prototype.unmute = function(moderatorUser, username, channelName, callback) {
var self = this;
var now = new Date();
if (!lib.hasOwnProperty(self.muted, username))
return callback('USER_NOT_MUTED');
var shadow = self.muted[username].shadow;
delete self.muted[username];
var msg = {
date: now,
type: 'unmute',
message: null,
moderator: moderatorUser.username,
username: username,
shadow: shadow,
bot: false
};
//If mute shadow inform only mods about it
if (shadow) {
self.io.to('moderators').emit('msg', msg);
self.io.to('mod:'+channelName).emit('msg', msg);
//If regular mute send mute message to the channel
} else {
self.io.to(channelName).emit('msg', msg);
self.io.to('moderators').emit('msg', msg);
}
callback(null);
};
//Send an error to the chat to a client's socket
function sendErrorChat(socket, message) {
socket.emit('msg', {
date: new Date(),
type: 'error',
message: message
});
}
//Send an error event to a client's socket
function sendError(socket, description) {
console.warn('Chat client error ', description);
socket.emit('err', description);
}
function isChannelNameInvalid(channelName) {
return (typeof channelName !== 'string' || channelName.length < 1 || channelName.length > 100);
}
function isChannelNameModsOnly(channelName) {
return /^mod:/.test(channelName);
}
module.exports = Chat;
Well, I may be wrong, but I feel like that's not a piece of code you wrote, so you lack the deep knowledge of what's going on behind the hood. I'd suggest you to start something 100% from scratch without copying from tutorials to build a more solid knowledge of the tech you're using, but you're free to follow any path you prefer. Anyway, the error is clearly given from the method :
function isChannelNameInvalid(channelName) {
return (typeof channelName !== 'string' || channelName.length < 1 || channelName.length > 100);
}
So I guess you should give us a bit more insight on the channel name you used.

webRTC datachannel is not working in chrome62

I am newbie to webRTC. I tried to create a Chat application, sending a simple text message.
But getting this error:
Uncaught DOMException: Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open'
at HTMLButtonElement.
Here is my code.
index.html
<div class = "row">
<div class = "col-md-4 col-md-offset-4">
<h2> Please sign in</h2>
<input type = "email" id = "usernameInput"
class = "form-control formgroup" placeholder = "Enter Name"
required = "" autofocus = "" title="please Enter name">
<button id = "loginBtn" class = "btn btn-lg btn-primary btnblock">
Sign in</button>
</div>
</div>
</div>
<div id = "callPage" class = "call-page container">
<div class = "row">
<div class = "col-md-4 col-md-offset-4 text-center">
<div class = "panel panel-primary">
<div class = "panel-heading">Text chat</div>
<div id = "chatarea" class = "panel-body text-left"></div>
</div>
</div>
</div>
<div class = "row text-center">
<div class = "col-md-12">
<input id = "msgInput" type = "text" placeholder = "Enter message" />
<button id = "sendMsgBtn" class = "btn-success btn">Send</button>
</div>
</div>
</div>
<script >
var name;
var connectedUser;
var conn = new WebSocket('ws://localhost:8000');
conn.onopen = function () {
console.log("Connected to the signaling server");
};
//when we got a message from a signaling server
conn.onmessage = function (msg) {
console.log("Got message", msg.data);
var data =JSON.parse( msg.data);
// console.log(data.type);
switch(data.type) {
case "login":
handleLogin(data.success);
break;
//when somebody wants to call us
case "offer":
handleOffer(data.offer, data.name);
break;
case "answer":
handleAnswer(data.answer);
break;
//when a remote peer sends an ice candidate to us
case "candidate":
handleCandidate(data.candidate);
console.log('candidate');
break;
case "leave":
handleLeave();
break;
default:
break;
}
};
conn.onerror = function (err) {
console.log("Got error", err);
};
//alias for sending JSON encoded messages
function send(message) {
//attach the other peer username to our messages
if (connectedUser) {
message.name = connectedUser;
}
conn.send(JSON.stringify(message));
};
var loginPage = document.querySelector('#loginPage');
var usernameInput = document.querySelector('#usernameInput');
var loginBtn = document.querySelector('#loginBtn');
var callPage = document.querySelector('#callPage');
var callToUsernameInput = document.querySelector('#callToUsernameInput');
// var callBtn = document.querySelector('#callBtn');
// var hangUpBtn = document.querySelector('#hangUpBtn');
var msgInput = document.querySelector('#msgInput');
var sendMsgBtn = document.querySelector('#sendMsgBtn');
var chatArea = document.querySelector('#chatarea');
var yourConn;
var dataChannel;
callPage.style.display = "none";
// Login when the user clicks the button
loginBtn.addEventListener("click", function (event) {
name = usernameInput.value;
if (name.length > 0) {
send({
type: "login",
name: name
});
}
});
function handleLogin(success) {
if (success === false) {
alert("Ooops...try a different username");
} else {
loginPage.style.display = "none";
callPage.style.display = "block";
//using Google public stun server
var configuration = {
"iceServers": [{ "url": "stun:stun2.1.google.com:19302" }]
};
yourConn = new RTCPeerConnection(configuration,{optional: [{RtpDataChannels: true}]});
// Setup ice handling
yourConn.onicecandidate = function (event) {
console.log('enter into login');
if (event.candidate) {
send({
type: "candidate",
candidate: event.candidate
});
}
};
//creating data channel
dataChannel = yourConn.createDataChannel("channel", {reliable:true});
dataChannel.onerror = function (error) {
console.log("Ooops...error:", error);
};
//when we receive a message from the other peer, display it on the screen
dataChannel.onmessage = function (event) {
chatArea.innerHTML += connectedUser + ": " + event.data + "<br />";
};
dataChannel.onclose = function () {
console.log("data channel is closed");
};
}
};
//when we got an answer from a remote user
function handleAnswer(answer) {
yourConn.setRemoteDescription(new RTCSessionDescription(answer));
};
//when we got an ice candidate from a remote user
function handleCandidate(candidate) {
yourConn.addIceCandidate(new RTCIceCandidate(candidate));
};
//when user clicks the "send message" button
sendMsgBtn.addEventListener("click", function (event) {
var val = msgInput.value;
chatArea.innerHTML += name + ": " + val + "<br />";
//sending a message to a connected peer
dataChannel.send(val);
msgInput.value = "";
});
</script>
server.js
var WebSocket = require('ws').Server;
var Port= 8000;
//creating a websocket server at port 9090
var wss = new WebSocket({port: Port});
var fs=require('fs');
var http=require('http');
console.log("STARTED");
var server = http.createServer(function (req, resp) {
fs.readFile("index.html", function (error, pgResp) {
if (error) {
resp.write('Contents you are looking are Not Found');
} else {
resp.end(pgResp);
}
});
});
server.listen(3000);
//all connected to the server users
var users = {};
//when a user connects to our sever
wss.on('connection', function(connection) {
console.log("User connected");
//when server gets a message from a connected user
connection.on('message', function(message) {
var data;
//accepting only JSON messages
try {
data = JSON.parse(message);
} catch (e) {
console.log("Invalid JSON");
data = {};
}
//switching type of the user message
switch (data.type) {
//when a user tries to login
case "login":
console.log("User logged", data.name);
//if anyone is logged in with this username then refuse
if(users[data.name]) {
sendTo(connection, {
type: "login",
success: false
});
} else {
//save user connection on the server
users[data.name] = connection;
connection.name = data.name;
sendTo(connection, {
type: "login",
success: true
});
}
break;
case "offer":
//for ex. UserA wants to call UserB
console.log("Sending offer to: ", data.name);
//if UserB exists then send him offer details
var conn = users[data.name];
if(conn != null) {
//setting that UserA connected with UserB
connection.otherName = data.name;
sendTo(conn, {
type: "offer",
offer: data.offer,
name: connection.name
});
}
break;
case "answer":
console.log("Sending answer to: ", data.name);
//for ex. UserB answers UserA
var conn = users[data.name];
if(conn != null) {
connection.otherName = data.name;
sendTo(conn, {
type: "answer",
answer: data.answer
});
}
break;
case "candidate":
console.log("Sending candidate to:",data.name);
var conn = users[data.name];
if(conn != null) {
sendTo(conn, {
type: "candidate",
candidate: data.candidate
});
}
break;
case "leave":
console.log("Disconnecting from", data.name);
var conn = users[data.name];
conn.otherName = null;
//notify the other user so he can disconnect his peer connection
if(conn != null) {
sendTo(conn, {
type: "leave"
});
}
break;
default:
sendTo(connection, {
type: "error",
message: "Command not found: " + data.type
});
break;
}
});
//when user exits, for example closes a browser window
//this may help if we are still in "offer","answer" or "candidate" state
connection.on("close", function() {
if(connection.name) {
delete users[connection.name];
if(connection.otherName) {
console.log("Disconnecting from ", connection.otherName);
var conn = users[connection.otherName];
conn.otherName = null;
if(conn != null) {
sendTo(conn, {
type: "leave"
});
}
}
}
});
connection.send(JSON.stringify("Hello world"));
});
function sendTo(connection, message) {
connection.send(JSON.stringify(message));
}
I have searched many posts and tried removing "{optional: [{RtpDataChannels: true}]}" ,set reliable=false. But still facing the same problem.Is it the chrome version problem? I am using Version 62.0.3202.75 (Official Build) (32-bit) of chrome.

Resources