Daily Learnings (June 3,2016)
I was working on a small project today using my computer’s microphone and the socket.io library to connect users to a local server. Below are some of the things that I had struggled with, and what ended up solving the issue, although these are by no means the “best” solutions.
- Setting up the socket connection after server.on
To set up the server on my local box, I used express and socket.io:
var socketio= require(‘socket.io’);
var express = require(‘express’);
var app = express();
var path = require(‘path’);
var http = require(‘http’)
var server = http.createServer()
var PORT = 3000;
var io = socketio(server)
io.on(‘connection’, function(socket){
console.log(“New client: “,socket.id);
})
server.on(‘request’, app);
server.listen(PORT, function () {
console.log(‘Server listening on PORT’, PORT);
})
However, doing this seems to trigger an error with multiple responses being sent:
Error: Can’t set headers after they are sent.
If I initialize the socket after the server.on call, everything seems to work better:
var socketio= require(‘socket.io’);
var express = require(‘express’);
var app = express();
var path = require(‘path’);
var http = require(‘http’)
var server = http.createServer()
var PORT = 3000;
server.on(‘request’, app);
server.listen(PORT, function () {
console.log(‘Server listening on PORT’, PORT);
})
var io = socketio(server)
io.on(‘connection’, function(socket){
console.log(“New client: “,socket.id);
})
Alternatively, if I pass the express app into the server during server initialization, everything seems to work smoothly as well:
var socketio= require(‘socket.io’);
var express = require(‘express’);
var app = express();
var path = require(‘path’);
var http = require(‘http’)
var server = http.createServer(app) //pass in app here
var PORT = 3000;
var io = socketio(server)
server.listen(PORT, function () {
console.log(‘Server listening on PORT’, PORT);
})
io.on(‘connection’, function(socket){
console.log(“New client: “,socket.id);
})
2. Passing the socket ID back to the client
I wanted to keep track of each client that was connected to my server, and one way was for the client to pass the server their socket ID whenever they made a request. However, having the socket emit a signal with the socket ID upon socket connection did not seems to work:
io.on(‘connection’, function(socket){
console.log(“New client: “,socket.id); //server knows socket ID
socket.emit(“SocketID”,socket.id); //server sends ID back to client, but client never receives it
})
One roundabout method that I did find to work involved having the client broadcast an additional signal to the server when the client connects, and then sending the socket ID back to the client:
//client side code
var socket = io(window.location.origin);
socket.on(‘connect’, function(){
console.log(“You’re connected!”);
socket.emit(‘whoami’);
})
//server side code
io.on(‘connection’, function(socket){
console.log(“New client: “,socket.id);
socket.on(‘whoami’, function(){
socket.emit(“socketid”, socket.id); //received by client
});
})
3. Learning to use the Web Audio API
Web Audio API is a very powerful and useful tool for dealing with web audio (both input and output). This was my first time using it, so it was a struggle to get everything set up; specifically, I used the volume-meter.js library to detect the volume of the sound that was coming into my laptop microphone.
At a high level, the process was fairly simple to understand, although there is likely a lot more going on underneath the hood:
window.AudioContext = window.AudioContext || window.webkitAudioContext; //sets the AudioContext
var foo = new AudioContext(); //create new AudioContext
try {
navigator.getUserMedia( // ask for an audio input
{
“audio”: {
“mandatory”: {
“googEchoCancellation”: “false”,
“googAutoGainControl”: “false”,
“googNoiseSuppression”: “false”,
“googHighpassFilter”: “false”
},
“optional”: []
},
}, gotStream, didntGetStream);
} catch (e) {
alert(‘getUserMedia threw exception :’ + e);
}
function didntGetStream() {
alert(‘Stream generation failed.’); //output if failed
}
var mediaStreamSource = null;
function gotStream(stream) {
mediaStreamSource = foo.createMediaStreamSource(stream); //create MediaStreamSource
var meter = createAudioMeter(foo); //create the audio meter
mediaStreamSource.connect(meter); //connect the meter to the MediaStreamSource
}