Push notifications using Node.js socket.io on apache web-server - apache

I am trying to understand how this all push notifications works. I tried to do some test of push technology but so far i failed.
The base assumptions are:
1) use Apache web-server as the main application web-server (mandatory since all our code is using that)
2) Cross-Browser push notification server in node.js Technology (offered socket.io since it is crossed browser).
So far i failed and here is my code (p1.html):
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>P1</title>
</head>
<body>
<h1>P1</h1>
<section id="content"></section>
<script src="/socket.io.js"></script> <!--socket.io-->
<script src="/socket.js"></script> <!--socket.io-client-->
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('notification', function (data) {
$('#content').append(data.message + '<br>')
});
</script>
</body>
</html>
and my server script (p1.js):
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, url = require('url')
app.listen(8080);
console.log("creating a connection");
io.sockets.on( 'connection', function ( socket ) {
console.log("runing time");
sendTimeMessage(socket);
});
function sendTimeMessage(socket){
console.log("in time");
var time= new Date().getTime();
console.log(time);
socket.volatile.emit( 'notification' , time );
setTimeout(sendTimeMessage, 5000);
}
function handler (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("");
}
function sendMessage(message) {
io.sockets.emit('notification', {'message': message});
}
i changed the IPs to local host for the example so i hope there is no mistake on the syntax.
when i run, the Apache web-server is the one that display the data and the idea is for the socket-io to update few fields.
current state:
1. If i don't add the socket.io-client js file i get reference error for socket.io-client
2. If i do add socket.io-client i get "ReferenceError: require is not defined
[Break On This Error] 'undefined' != typeof io ? io : module.exports
i can really need help understanding it, and making it work. i am also open minded to alternative solutions
i can really need help getting this done.

Working example, of what you want to achieve. First mistake is wrong javascript path on client-side, the right one is /socket.io/socket.io.js. Second mistake is use of socket.volatile which doesn't exist.
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, url = require('url')
console.log("creating a connection");
io.sockets.on( 'connection', function ( socket ) {
console.log("runing time");
sendTimeMessage(socket);
});
function sendTimeMessage(socket){
console.log("in time");
var now= new Date().getTime();
socket.emit('notification', {'message': now});
setTimeout(function() {
socket.emit('notification', {'message': "after 5s"});
},5000);
}
function handler (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end("<html><script src=\"/socket.io/socket.io.js\"></script> <!--socket.io--><script>io.connect().on('notification', function (data) {console.log(data)});</script></html>");
}
app.listen(8080);

Ok, i partially solved the with a huge help from the guys on IRC i created an:
1) HTML over Apache on port 80
2) live notification service update my HTML over port 8080
(there might still have code issue in the values arrived from the functions cause its not fully debuged)
p1.html (client)
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<section id="content"></section>
<script src="/node_modules/socket.io-client/dist/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
var socket = io.connect('http://10.10.10.1:8080');
socket.on('notification', function (from,msg) {
$('#content').append(msg.message + '<br>')
});
</script>
</body>
</html>
p1.js (service)
var io = require('socket.io').listen(8080)
console.log("creating a connection");
io.sockets.on( 'connection', function ( socket ) {
console.log("runing time");
var oldtime= new Date().getTime();
while (1){
var newtime= new Date().getTime();
if (newtime%5323==0 && newtime != oldtime){
oldtime = newtime;
console.log(newtime);
socket.emit( 'notification' , {'message': "the time is - " + newtime} );
}
}
});
enjoy

Thanks #yanger
I was helped by your code.
I want to add a comment.
But I can't use comment yet.
In my case, I want to make a real time alarm.
and I use 80 port web server and 81 port alarm server.
So I just use this code. (Client.js)
var socket = io.connect(':81');
It's totally working.
I wish someone would read this article and get help.

Related

URL.createObjectURL(mediaSource) - play back video from URL - MOOV atom - Elastic Transcoder

I am trying to play back a video (currently hosted on S3 with public access) by creating a blob URL.
I have used Elastic Transcoder to encode the video since it is supposed to set the MOOV atom to the top (beginning).
I am unable to get the code to work but also found a working example: link here
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
mediaSource.endOfStream();
video.play();
//console.log(mediaSource.readyState); // ended
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
What am I doing wrong? I looked at tools ie.e MP4Box or QT-FastStart but they seem to be kind of old school. I would also be willing to change from MP4 to M3U8 playlist but then I don't know what MIME types to use.
At the ned of the day I am trying to play back a video/stream and hide the URL (origin) potentially using blob.
Thank you guys!
So, first, even though this code seems to be taken from mozilla documentation site, there are a few issues - you are not checking the readyState before calling endOfStream thus the error you get is valid, secondly, the play() call is blocked by the autoplay policy changes. If you add an error handler, you will actually see that the appendBuffer fails. Here is the updated snippet:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
// console.log(mediaSource.readyState); // ended
if (mediaSource.readyState === "open") {
mediaSource.endOfStream();
video.play();
}
});
sourceBuffer.addEventListener('error', function (event) {
console.log('an error encountered while trying to append buffer');
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
So lets advance to next issue - the actual error. So, using chrome://media-internals/ we can see that the video actually fails to load do to incompatibility with the ISOBMFF format:
I am not familiar with Elastic Transcoder, but it seems that is it not producing an mp4 file suitable for live streaming. Also, if using mse, putting moov at the beginning is not enough, the video actually has to meet all of the ISOBMFF requirements - see chapters 3. and 4.
The working sample you mentioned is not a valid comparison since it uses the blob for the src, where the ISOBMFF rules do not apply. If it is fine for you to go that way, don't use MSE and put the blob directly in the src. If you need MSE, you have to mux it correctly.
Ok, so I got the original code example to work by encoding my MP4 videos with ffmpeg:
ffmpeg -i input.mp4 -vf scale=1920:1080,setsar=1:1 -c:v libx264 -preset medium -c:a aac -movflags empty_moov+default_base_moof+frag_keyframe output.mp4 -hide_banner
Important is: -movflags empty_moov+default_base_moof+frag_keyframe
This setup also scales the video to 1920x1080 (disregarding any aspect ratio of the input video)
However, based on the comments of the original post, I do believe there might be a more efficient way to generate the blob url and ingest into a video tag. This example was copied straight from https://developer.mozilla.org.
If anyone comes up with a better script (not over-engineered), please post it here.
Thank you #Rudolfs Bundulis for all your help!

Google SignIn State

I'm trying to build a Google signin button into my website. I'm trying to avoid using their built-in button. The code below works to sign in a user, but I can't figure out how to make my webpage remember that they're signed in when the user refreshes the page, or leaves the site and comes back.
Using Chrome's developer tools, I can see that there's an entry for https://accounts.google.com under both Local Storage and Session Storage. They seem to more or less contain the same information, including the user's validated token.
What I don't understand is how to get the gapi.auth2.init() function to recognize and use this token. The documentation doesn't seem to cover it.
<html>
<head>
<title>Login Test</title>
<script src="http://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://apis.google.com/js/platform.js?onload=renderButton" async defer></script>
</head>
<script>
var googleUser = {};
function renderButton() {
gapi.load('auth2', function(){
auth2 = gapi.auth2.init({
client_id: 'MY_CREDENTIALS.apps.googleusercontent.com',
});
attachSignin(document.getElementById('customBtn'));
});
};
function attachSignin(element) {
auth2.attachClickHandler(element, {},
function(googleUser) {
document.getElementById('name').innerText = "Signed in: " +
googleUser.getBasicProfile().getName();
}, function(error) {
alert(JSON.stringify(error, undefined, 2));
}
);
}
</script>
<body>
<div id="gSignInWrapper">
<span class="label">Sign in with:</span>
<input type="button" id="customBtn" value="Google"></input>
</div>
<p id="name"></p>
</body>
</html>
You can use listeners. This is the relevant part:
// Listen for sign-in state changes.
auth2.isSignedIn.listen(signinChanged);
// Listen for changes to current user.
auth2.currentUser.listen(userChanged);
You can also get up to date values by
var isSignedIn = auth2.isSignedIn.get();
var currentUser = auth2.currentUser.get();
To strictly detect returning users only you can do:
var auth2 = gapi.auth2.init(CONFIG);
auth2.then(function() {
// at this point initial authentication is done.
var currentUser = auth2.currentUser.get();
});
When it comes to your code I would do:
auth2 = gapi.auth2.init(CONFIG);
auth2.currentUser.listen(onUserChange);
auth2.attachClickHandler(element, {});
This way all changes in sign-in state are passed to onUserChange (this includes returning users, new sign-ins from attachClickHandler, new sign-ins from different tab).

Auto-Redirecting after BigVideo.js video ends

I'm having trouble auto-redirecting after my video has ended using BigVideo.js. Not sure what's wrong here. Not only does this not redirect it completely breaks the player and the video does not play.
<script type="text/javascript">
var BV;
$(function() {
// initialize BigVideo
BV = new $.BigVideo();
BV.init();
BV.show('vids/video.mp4');
BV.getPlayer().on("ended", function() {
window.location = "http://www.google.com";
})
});
</script>
I tested your code locally and the redirection worked without any problems.
I guess it depends on the browser type/version or other environment factor.
Try to properly unload the video element by:
BV.getPlayer().on("ended", function () {
this.pause();
delete(this);
window.location = "http://www.google.com";
});
reference:
How to properly unload/destroy a VIDEO element
hope that will do the trick :)

XMLHttpRequest in a ContentScript from the Firefox SDK (Cross-Domain)

I am porting a chrome extension to firefox and want to keep as much code as possible. I am working with the sdk and I am new with JavaScript, so please bear with me if it is just a nooby mistake ;)
I need to get some stuff via a couple of XMLHttpRequests in content-scripts.
The "firefox-way" of doing things would be to use the sdk-request-api and work via messages between the main- and the content-script like so. Besides the fact that it would mean a lot of work for me to implement this throughout the whole addon, I also need to get binary data, which seems not to be possible.
The workaround for this is documented here. I would prefer to avoid this, since I think I read somewhere that it is a beta-feature right now and it seems to be pretty "work-aroundy".
Ideally I would like to implement it this way. In the upcoming Firefox 24 it should be possible to allow content scripts to access certain domains. Therefore I am using Firefox Aurora right now. I added the following code to my package.json:
"permissions": {
"cross-domain-content": ["http://mozilla.org"]
}
My main.js creates a panel when a button is clicked and loads the scripts into it:
var testPanel = require("sdk/panel").Panel({
contentURL: data.url("pages/background.html"),
contentScriptFile: [data.url("util/jquery-1.8.2.min.js"), data.url("pages/xhrTest.js")]
})
testPanel.show();
And this is my xhrTest.js:
var xhr = new XMLHttpRequest();
xhr.open("GET","http://mozilla.org",true);
xhr.onerror = function () {
console.log("Error");
};
xhr.onload = function () {
console.log("loaded");
}
xhr.send();
While debugging, it jumps from status 2 to 4 with an empty response and calls the "onerror". The status is 0, statustext is empty and I don't see any other indicators of what went wrong.
Now I don't know if this is still the same-origin-policy blocking me, or if I did something else wrong?
I'd really appreciate any help I can get :)
Thanks in advance,
Fabi
Hrm, I can't really see a glaring error. Here is an example add-on based on the docs that does work, at least it does for me in Firefox 24 Beta:
Main.js:
// main.js
var data = require("sdk/self").data;
var panel = require("sdk/panel").Panel({
height: 250,
contentURL: data.url("panel.html"),
contentScriptFile: data.url("panel-script.js")
});
panel.on("show", function(){
panel.port.emit("show");
});
require("sdk/widget").Widget({
id: "test-widget",
label: "Test-Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
panel: panel
});
Panel.html:
<!doctype HTML>
<html>
<meta charset="utf-8">
<head></head>
<body>
<pre id="forecast_summary"></pre>
</body>
</html>
Content script:
// panel-script.js
var url = "https://hn-test.firebaseio.com/articles/e5b10c82600b51732af584583a7f57c4a7c01bff.json";
self.port.on("show", function () {
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.onload = function () {
var element = document.getElementById("forecast_summary");
// formatting
var pretty = JSON.stringify(JSON.parse(request.responseText), null, ' ');
element.textContent = pretty;
};
request.send();
});
Package.json:
{
"name": "jp-crossdomain-xhr",
"fullName": "jp-crossdomain-xhr",
"id": "jid1-B2RaQxOBKox8wA",
"description": "a basic add-on",
"author": "",
"license": "MPL 2.0",
"version": "0.1",
"permissions": {
"cross-domain-content": ["https://hn-test.firebaseio.com"]
}
}
Github Repo

Object not found near navigator.webkitGetUserMedia() and NavigatorUserMediaError in webrtc

I started to learn webrtc when I tried to implement the basic sample application
<html>
<head>
</head>
<body>
<script type="text/javascript">
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia({video: true}, function(localMediaStream) {
var video = document.createElement("video");
video.autoplay = true;
video.src = window.URL.createObjectURL(localMediaStream);
document.body.appendChild(video);
}, function(error) {
console.log(error);
});
</script>
</body>
</html>
I used this code to run in locaL browser google canary I enabled peerconnection and I didnot found mediastream in my browser but I think it might enabled as defalut in my browser.
The problem is this code results as NavigatorUserMediaError in console.i am not finding the way to step out from this problem.
Any one have idea where I went wrong in my code.
Did you run this from a web server?
If you run it from a file:// URL, you'll get a NavigatorUserMediaError.
I just tried your code from localhost in Chrome 22.0 and it works fine.
Note that this example does not use RTCPeerConnection and you don't have to enable any flags now in Chrome.