##Concept
We have a web app where people type in their “channel” preferences (#food, #fitness, #productivity) and our program re-routes them to a video chat room where others who have the same (#food) preferences can video chat.
While not a novel idea (and prone to pornography), this is something I would like to build out.
Primarily because I want to learn,
parsing string queries accurately (#food e.g from a line of text),
re-routing to other channels
auto video calling others (by collecting peer_ids)
displaying parallel videos on the same page
My first attempt is to build this as a chrome extension because of its non-envasive nature, and since an extension isn’t really an app, or a webpage I thought it would be a nice chat room utility.
First try - extension:
Let’s setup the socket server:
var https = require ( 'https' );
var fs = require ( 'fs' ); // Using the filesystem module
var url = require ( 'url' );
var socket = require ( 'socket.io' );
var options = {
key : fs . readFileSync ( 'my-key.pem' ),
cert : fs . readFileSync ( 'my-cert.pem' )
} ;
function handleIt ( req , res ) {
var parsedUrl = url.parse(req.url);
var path = parsedUrl.pathname;
if (path == "/") {
path = "popup.html";
}
fs .readFile ( __dirname + path ,
// Callback function for reading
function ( err , fileContents ) {
// if there is an error
if (err) {
res.writeHead(500);
return res.end('Error loading ' + req.url);
}
res .writeHead ( 200 );
res .end ( fileContents );
}
);
console .log ( "Got a request " + req .url );
}
var io = require ( 'socket.io' ) .listen ( httpServer );
io .sockets.on ( 'connection' , function ( socket ) {
console.log("We have a new client : " + socket.id);
socket.on('chatmessage', function (data) {
console.log(" message : " + data);
socket.broadcast.send(data);
});
// socket.on('otherevent', function(data) {
// console.log(" Received : 'otherevent' " + data);
// });
socket.on('disconnect', function() {
console.log(" Client has disconnected ");
});
});
var httpServer = https.createServer(options, handleIt);
httpServer.listen(8080, function(){
console.log(" 8080 ! listen up !" );
} );
Because extensions cry every time there’s in-line code or script code running in html, we make a separate socket-stuff.js file
var socket = io .connect ( "https://104.131.109.131:8080" );
socket .on ( 'connect' , function () {
console.log("Connected");
} );
socket .on ( 'chatmessage' , function ( data ) {
console.log(data.text);
chrome.runtime.sendMessage({ msg : "socket" , text : data . text } , function ( response ) {} );
document .getElementById ( 'messages' ) .innerHTML = "" + data + "" + document .getElementById ( 'messages' ) .innerHTML ;
} );
function sendMessage ( message ) {
console.log(" chatmessage : " + message );
socket.emit('chatmessage', message);
} ;
and call it in popup.html
< html >
< head >
< style >
body {
font-size : 30px ;
background : yellow ;
width : 300px ;
height : 300px
}
</ style >
<! -- < script src = "jquery.js" ></ script > -- >
< script src = "p5.js" type = "text/javascript" ></ script >
< script src = "my-js.js" type = "text/javascript" ></ script >
< script src = "popup.js" type = "text/javascript" ></ script >
< script src = "p5.dom.js" type = "text/javascript" ></ script >
< script src = "socket.io.js" type = "text/javascript" ></ script >
< script src = "socket-stuff.js" type = "text/javascript" ></ script >
< body >
< div id = "status" ></ div >
< div id = "thevideo" width = "100" height = "100" ></ videos >
< div id = "messages" >
No Messages Yet
</ div >
< input type = "text" id = "message" name = "message" >
< input type = "submit" value = "submit" >
<! -- < input type = "submit" value = "submit" onclick = "sendMessage(document.getElementById('message').value);" > -- >
</ body >
</ head >
</ html >
Voila - results!
Console
Yeah - getting to these was an effort in itself and after consulting yourself and Sam Lavigne, and Stackoverflow I stopped trying to get sockets to work over chrome extensions.
What did I do next…
Build Channels … on a regular webpage
I figured out the flow and wrote the functions to route
User arrives at home
gets a peer_id
Iputs channel preference
Hash(tag) check function runs
re-directing to new web-page
< html >
< script src = "peer.min.js" ></ script >
< script type = "text/javascript" >
// We 'll use a global variable to hold on to our id from PeerJS
var peer_id = null;
//your own video that' s gonna get beamed to videochat channel
window .URL = window .URL || window .webkitURL || window .mozURL || window .msURL ;
navigator .getUserMedia = navigator .getUserMedia || navigator .webkitGetUserMedia || navigator .mozGetUserMedia ;
// my video has to show , so this is the getUserMedia for that :
if ( navigator .getUserMedia ) {
navigator.getUserMedia({ video : true , audio : true } , function ( stream ) {
my_stream = stream;
var videoElement = document.getElementById('myvideo');
videoElement.src = window.URL.createObjectURL(stream) || stream;
videoElement.play();
//using Shawn's peer server
peer = new Peer({ host : 'liveweb.itp.io' , port : 9000 , path : '/' } );
// Get an ID from the PeerJS server 5
peer .on ( 'open' , function ( id ) {
console.log('My peer ID is : ' + id);
peer_id = id;
//Here, pass peer_id to foodChannel()
foodChannel.push(peer_id);
});
}
}
function hashCheck(hashtag){
var hash = hashtag;
//scrapes input text for hashtags
if (hash == "#food"){
foodChannel();
}
}
function foodChannel(){
//received peer_id
//call other peers here or food.html?
//redirect to food.html
window.open(' https :// osamasehgol . com : 8080 / food . html ? peer_id = '+peer_id);
}
</script>
<body>
<h4>Channel search</h4>
<input type="text" value="#food, #fitness..." id="channel"></input>
<button onclick ="hashCheck(documentGetElementById(' channel ' ). value ); ">send</button>
</body>
</html>
On the food page, you have your peer_id coming in along with your getUserMedia. But I couldn’t figure out how to get other peoples peer_id and dial them.
< html >
<! -- This is the food channel -- >
< script src = "peer.min.js" ></ script >
< script type = "text/javascript" >
// receive your peer_id
// receive others peer_id
// call eachother
if ( navigator .getUserMedia ) {
navigator.getUserMedia({ video : true , audio : true } , function ( stream ) {
my_stream = stream;
var videoElement = document.getElementById('myvideo');
videoElement.src = window.URL.createObjectURL(stream) || stream;
videoElement.play();
peer.on('call', function(incoming_call){
console.log("...call...");
incoming_call.answer(my_stream); //answering call with my stream
incoming_call.on('stream', function(remoteStream){
//getting stream from other callers
//attaching to video object
var ovideoElement = document.createElement('video');
ovideoElement.src = window.URL.createObjectURL(remoteStream) || remoteStream;
ovideoElement.setAttribute("autoplay", "true");
ovideoElement.play();
document.body.appendChild(ovideoElement);
} );
} );
} , function ( err ) {
console.log('Failed to get local stream' ,err);
} );
}
// create video div per peer_id
var call = peer .call ( peeridtocall , my_stream );
call .on ( 'stream' , function ( remoteStream ) {
var ovideoElement = document.createElement('video');
ovideoElement.src = window.URL.createObjectURL(remoteStream) || remoteStream;
ovideoElement.setAttribute("autoplay", "true");
ovideoElement.play();
document.body.appendChild(ovideoElement);
} );
// broadcast to all peers
</ script >
< body >
</ body >
</ html >
It didn’t work and no helpful errors
For completeness stating, Server.js stays the same
// HTTP Portion
var http = require ( 'https' );
var fs = require ( 'fs' ); // Using the filesystem module
var url = require ( 'url' );
var options = {
key : fs . readFileSync ( 'my-key.pem' ),
cert : fs . readFileSync ( 'my-cert.pem' )
} ;
var httpServer = http .createServer ( options , requestHandler );
httpServer .listen ( 8080 , function () {
console.log("listening on 8080");
} );
function requestHandler ( req , res ) {
var parsedUrl = url.parse(req.url);
console.log("The Request is : " + parsedUrl.pathname);
// Read in the file they requested
fs.readFile(__dirname + parsedUrl.pathname,
// Callback function for reading
function (err, data) {
// if there is an error
if (err) {
res.writeHead(500);
return res.end('Error loading ' + parsedUrl.pathname);
}
// Otherwise, send the data, the contents of the file
res.writeHead(200);
res.end(data);
}
);
}
// WebSocket Portion
// WebSockets work with the HTTP server
var io = require('socket.io').listen(httpServer);
// Register a callback function to run when we have an individual connection
// This is run for each individual user that connects
io.sockets.on('connection',
// We are given a websocket object in our function
function (socket) {
console.log(" We have a new client : " + socket.id);
// When this user " send " from clientside javascript, we get a " message "
// client side: socket.send(" the message "); or socket.emit('message', " the message ");
socket.on('message',
// Run this function when a message is sent
function (data) {
console.log(" message : " + data);
// Call " broadcast " to send it to all clients (except sender), this is equal to
// socket.broadcast.emit('message', data);
socket.broadcast.send(data);
// To all clients, on io.sockets instead
// io.sockets.emit('message', " this goes to everyone ");
}
);
// When this user emits, client side: socket.emit('otherevent',some data);
socket.on('image', function(data) {
// Data comes in as whatever was sent, including objects
console.log(" Received : 'image' ");
socket.broadcast.emit('image',data);
});
socket.on('disconnect', function() {
console.log(" Client has disconnected " );
} );
}
);
I hate Programming
But really… I dont. I have my reasons for doing it. I’ll try again tomorrow,
“Have a drink of water and get some sleep. Wake up in the morning and try again like everybody else”
and listen to Louis CK,
VIDEO
Source: Louie - Season 2, Episode 9: Eddie