Possible errors(bugs) which might hamper opentok video chat application - javascript

My issue of concern is to find out the possible mistakes in my code which might hamper the working of opentok services to run smoothly(without any error) in my code. There something might be going wrong with my code. Please examine How Am I ending any video chat through my code.And other codes might have been written incorrectly
The library version I'm using is this
<script type="text/javascript" src="http://static.opentok.com/webrtc/v2.2/js/TB.min.js" ></script>
I'm using dot net sdk to generate sessionId and tokens on server side
I have published my application online , and it runs well 30 % time but 70% time it throws errors like sessionInfoError or many other errors
Api key secret and other settings aremade in web.config file like this
<appSettings>
<add key="opentok_key" value="******"/>
<add key="opentok_secret" value="***********************"/>
<add key="opentok_server" value="https://api.opentok.com"/>
<add key="opentok_token_sentinel" value="T1=="/>
<add key="opentok_sdk_version" value="tbdotnet"/>
Rest of the code and functions written with the help of tokbox documentation are like this
var sessionId;
var token;
var apiKey = "*******";
var publisher_connections = {};
var publisher;
var session;
var Id;
var streamedTime;
var hours;
var minutes;
var seconds;
function a() {
sessionId = document.getElementById('<%= hdn.ClientID%>').value;
token = document.getElementById('<%= hdn1.ClientID%>').value;
session = TB.initSession(sessionId);
session.addEventListener("sessionConnected", sessionConnectedHandler);
session.addEventListener('sessionDisconnected', sessionDisconnectedHandler);
session.addEventListener("streamCreated", streamCreatedHandler);
session.addEventListener("sessionDestroyed", sessionDestroy);
session.addEventListener("signal", signalHandler);
session.addEventListener("streamDestroyed", streamDestroyedHandler);
session.addEventListener('connectionCreated', connectionCreatedHandler);
session.addEventListener('connectionDestroyed', connectionDestroyedHandler);
TB.addEventListener("exception", exceptionHandler);
TB.setLogLevel(TB.DEBUG);
session.connect(apiKey, token);
}
function sessionConnectedHandler(event) {
console.log("connected");
subscribeToStreams(event.streams);
session.publish();
}
function sessionDisconnectedHandler(event) {
alert("Session Disconnected");
for (var i = 0; i < event.streams.length; i++) {alert(event.streams[i].connection.connectionId);
delete publisher_connections[event.streams[i].connection.connectionId];
}
publisher = null;
}
function streamCreatedHandler(event) {
console.log("created");
subscribeToStreams(event.streams);
for (var i = 0; i < event.streams.length; i++) {
publisher_connections[event.streams[i].connection.connectionId] = 1;
}
}
function subscribeToStreams(streams) {
for (var i = 0; i < streams.length; i++) {
var stream = streams[i];
if (stream.connection.connectionId != session.connection.connectionId) {
var subscriber = session.subscribe(stream);
if (stream.connection.data == "accept") {
alert(stream.connection.data + " Joined You");
startTimer();
}
else {
alert(stream.connection.data + " Joined You");
UpdateInitializedTime();
startTimer();
}
}
}
}
function exceptionHandler(event) {
alert(event.message);
}
function sessionDestroy(event) {
session.disconnect();
alert("Session Destroyed");
}
}
function streamDestroyedHandler(event) {
for (var i = 0; i < event.streams.length; i++) {
delete publisher_connections[event.streams[i].connection.connectionId];
//alert("Someone left you");
}
}
function connectionDestroyedHandler(event) {
alert(event.streams[i].connection.connectionId + " left the conversation");
// This signals that connections were destroyed
}
function connectionCreatedHandler(event) {
// This signals new connections have been created.
// alert("this");
// alert(connection.data);
}
There is a setInterval function which calls itself every second and will end video chat when fixed time become 00:00:00
function timeOver(){
if (hours == 00 && minutes == 00 && seconds == 00) {
session.disconnect();
alert("Time Given For this Video Chat is Over");
}
}
I have a button for disconnecting from session
<input type="button" value="Disconnect" id="btnDisconnect" onclick="sessionDestroy()" />
it calls the sessionDestroy() function on clicking
Please examine these codes like a doctor

You code looks alright. Please keep in mind that Stack Overflow is used to ask questions and solve bugs. Using it as a place to proofread your code is not the intended idea.

Related

Display a message upon the beginning and completion of a function in OSC API

The idea is to allow me to press a button on the HTML page to execute a command to copy and delete all photos on cameras with feedback showing at the beginning and ending of the execution.
At the moment, after clicking the "Get Images From Camera", the textarea is showing this text:
Executed command: \copyImages
Result is as below: Copying images from
both cameras...\n
And it goes on to copy and delete all images like I want. But at the end of this process, nothing is returned back to the screen, so the user has no idea what happens. The nature of callback in Node js makes it too confusing for me to figure out how to do this.
P.S. I've tried all I know before I come here to get your help. So know that any suggestions are very appreciated!
So, my question is how do I change the codes below so that I could
display a message to show the user that the copying is completed successfully like:
Please wait for the copying to complete...
Completed!
Below are the HTML markups
<button id="copyImages" type="button" class="button">Get Images From Camera</button>
<textarea id="output" readonly></textarea>
Here is the Javascript event handling:
copyImages.onclick = function() {
dest = '/copyImages';
writeToOutput(dest);
}
function writeToOutput(dest) {
$.get(dest, null, function(data) {
resultText += "Executed command: "+dest+"\n"
+"Result is as below: \n"+data;
$("#output").val(resultText);
}, "text");
return true;
}
These functions below are for setting up a Node App server using express module to listen to anything the HTML page passes to it. They are run on a different device.
expressServer.listen( expressPort, function() {
console.log('expressServer listening at *:%d', expressPort );
});
// allow CORS on the express server
expressServer.use(function(req, res, next) {
// enable cross original resource sharing to allow html page to access commands
res.header("Access-Control-Allow-Origin", "*");
// return to the console the URL that is being accesssed, leaving for clarity
console.log("\n"+req.url);
next();
});
expressServer.get('/copyImages', function (req, res) {
// user accesses /copyImages and the copyImages function is called
copyImages(function(result) {
res.end(result + "\n");
});
});
Copy images from Theta S Camera to Raspberry Pi and delete those from the cameras
var resultCopyImages = "";
copyImages = function (callback) {
resultCopyImages = "Copying images from both cameras...\n";
for (var i = 0; i < camArray.length; i++) {
copyOneCamImages(i, callback);
}
return (callback(resultCopyImages));
//how to return multiple messages?
}
copyOneCamImages = function (camID, callback) {
d.on('error', function(err){
console.log('There was an error copying the images');
return(callback('There was an error running a function, please make sure all cameras are connected and restart the server'));
})
d.run(function(){
var imageFolder = baseImageFolder + camID;
// if the directory does not exist, make it
if (!fs.existsSync(imageFolder)) {
fs.mkdirSync(imageFolder);
console.log("no 'images' folder found, so a new one has been created!");
}
// initialise total images, approximate time
var totalImages = 0;
var approxTime = 0;
// get the first image and do not include thumbnail
var entryCount = 1;
var includeThumb = false;
var filename;
var fileuri;
// get the total amount of images
camArray[camID].oscClient.listImages(entryCount, includeThumb)
.then(function (res) {
totalImages = res.results.totalEntries;
approxTime = totalImages * 5;
resultCopyImages = '';
resultCopyImages = 'Camera ' + (camID + 1) + ': Copying a total of: ' + totalImages + ' images'
+ '\nTo folder: ' + imageFolder
+ '\nThis process will take approximately: ' + approxTime + ' seconds \n';
console.log(resultCopyImages);
callback(resultCopyImages);
});
// copy a single image, with the same name and put it in images folder
camArray[camID].oscClient.listImages(entryCount, includeThumb)
.then(function (res) {
filename = imageFolder + '/' + res.results.entries[0].name;
fileuri = res.results.entries[0].uri;
imagesLeft = res.results.totalEntries;
// gets the image data
camArray[camID].oscClient.getImage(res.results.entries[0].uri)
.then(function (res) {
var imgData = res;
fs.writeFile(filename, imgData);
camArray[camID].oscClient.delete(fileuri).then(function () {
if (imagesLeft != 0) {
// callback to itself to continue copying if images are left
callback(copyOneCamImages(camID, callback));
//????????????????????????????????????????????????????????????????????????????
//if(imagesLeft==1) return(callback("Finished copying"));
}/* else {
resultCopyImages = "Finshed copying image.\n";
console.log(resultCopyImages);
}
else if
return(callback(resultCopyImages));
}*/
});
});
});
})
}
So far there is no real answer to the question I asked so we have concluded the project and skipped the feature. However, it's just the matter of mastering the REST API and the asynchronous functions in NodeJs. The project is expected to continue for a next version sometime next year.

How to fix "MasterPage is undefined" in javascript function?

I am currently supporting a web-based app in asp.net vb. This part of code below is for checking the session and automatically logs off the user after the expiration of session. Also, I have a security window that pops up upon the successful log in and also logs off the user whenever this pop up window is refreshed or closed.
The problem is I am having an error saying "MasterPage is Undefined" whenever the javascript is calling the functions in MasterPage.master.vb. The error occurs on code MasterPage.LogOn(), MasterPage.GetClientSession(), and the likes.
Below is my javascript in the MasterPage.master file and the functions LogOn(), GetClientSession() and others are on the MasterPage.master.vb file.
This issue only occurs upon the deployment of the system on the test server, and works fine on my local pc.
Anyone who can help please. Thanks so much.
<script type="text/javascript" language="JavaScript">
var SessionTime = 0;
var uname = "";
var status = "";
var clientSession = 0;
var spyOn;
function logon()
{
MasterPage.LogOn();
clientSession = MasterPage.GetClientSession().value;
spyOn = MasterPage.spyOn().value;
setTimeout("CheckSession()", 60000);
if (!spyOn)
{
var spyWin = open('spy.aspx','UserSecurity','width=250,height=100,left=2000,top=2000,status=0,scrollbar=no,titlebar=no,toolbar=no');
}
}
function CheckSession()
{
SessionTime = SessionTime + 1;
if (SessionTime >= clientSession)
{
var uname = document.getElementById("ctl00_hdnUser").value;
var status = document.getElementById("ctl00_hdnStatus").value;
var x = MasterPage.SessionEnded(uname, status).value;
alert(x);
window.open("Login.aspx","_self");
}
setTimeout("CheckSession()", 60000);
}
function RorC()
{
var top=self.screenTop;
if (top>9000)
{
window.location.href="logout.aspx" ;
}
}
function LogMeOut()
{
window.location.href="logout.aspx" ;
}
function ShowTime()
{
var dt = new Date();
document.getElementById("<%= Textbox1.ClientID %>").value = dt.toLocaleTimeString();
window.setTimeout("ShowTime()", 1000);
MasterPage.CheckSession(CheckSession_CallBack);
}
window.setTimeout("ShowTime()", 1000);
function CheckSession_CallBack(response)
{
var ret = response.value;
if (ret == "")
{
isClose = true;
window.location.href="login.aspx"
}
}
</script>
This can be fixed by adding handlers (<httphandlers> under <system.web> section and <handlers> under <system.webserver> section) on web.config that supports IIS7 and also setting the application pool on IIS manager from "Integrated" to "Classic".

Javascript 'onbeforeunload()' not working with a function call

I have this script below which is used in a survey. The problem I have is, onbeforeunload() works when I don't call a function inside it. If I make any function call(save_survey() or fetch_demographics()) inside it, the browser or the tab closes without any prompt.
<script type="text/javascript">
$(document).ready(function() {
$('#select_message').hide();
startTime = new Date().getTime();
});
loc = 0;
block_size = {{ block_size }};
sid = {{ sid }};
survey = {{ survey|tojson }};
survey_choices = '';
startTime = 0;
demographics_content = {};
function save_survey(sf)
{
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
var surveydat = '';
if(sf==1)
{ //Success
surveydat = 'sid='+sid+'&dem='+JSON.stringify(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+JSON.stringify(survey_choices);
}
if(sf==0)
{ //Fail
surveydat = 'sid='+sid+'&dem='+json_encode(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+json_encode(survey_choices);
}
//Survey Save Call
$.ajax({
type: 'POST',
url: '/save_surveyresponse/'+sf,
data: surveydat,
beforeSend:function(){
// this is where we append a loading image
$('#survey_holder').html('<div class="loading"><img src="/static/img/loading.gif" alt="Loading..." /></div>');
},
success:function(data){
// successful request; do something with the data
$('#ajax-panel').empty();
$('#survey_holder').html('Success');
alert("Dev Alert: All surveys are over! Saving data now...");
window.location.replace('http://localhost:5000/surveys/thankyou');
},
error:function(){
// failed request; give feedback to user
$('#survey_holder').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
}
function verify_captcha()
{
// alert($('#g-recaptcha-response').html());
}
function block_by_block()
{
var div_content ='<table border="0" cellspacing="10" class="table-condensed"><tr>';
var ii=0;
var block = survey[loc];
var temp_array = block.split("::");
if(loc>=1)
{
var radio_val = $('input[name=block_child'+(loc-1)+']:checked', '#listform').val();
//console.log(radio_val);
if(radio_val!=undefined)
survey_choices += radio_val +'\t';
else
{
alert("Please select one of the choices");
loc--;
return false;
}
}
for(ii=0;ii<block_size;ii++)
{
//Chop the strings and change the div content
div_content+="<td>" + temp_array[ii]+"</td>";
div_content+="<td>" + ' <label class="btn btn-default"><input type="radio" id = "block_child'+loc+'" name="block_child'+loc+'" value="'+temp_array[ii]+'"></label></td>';
div_content+="</tr><tr>";
}
div_content+='<tr><td><input type="button" class="btn" value="Next" onClick="survey_handle()"></td><td>';
div_content+='<input type="button" class="btn" value="Quit" onClick="quit_survey()"></td></tr>';
div_content+="</table></br>";
$("#survey_holder").html(div_content);
//return Success;
}
function updateProgress()
{
var progress = (loc/survey.length)*100;
$('.progress-bar').css('width', progress+'%').attr('aria-valuenow', progress);
$("#active-bar").html(Math.ceil(progress));
}
function survey_handle()
{
if(loc==0)
{
verify_captcha();
$("#message").hide();
//Save the participant data and start showing survey
fetch_demographics();
block_by_block();
updateProgress();
$('#select_message').show();
}
else if(loc<survey.length)
{
block_by_block();
updateProgress();
}
else if(loc == survey.length)
{
//Save your data and show final page
$('#select_message').hide();
survey_choices += $('input[name=block_child'+(loc-1)+']:checked', '#listform').val()+'\t';
//alert(survey_choices);
//Great way to call AJAX
save_survey(1);
}
loc++;
return false;
}
</script>
<script type="text/javascript">
window.onbeforeunload = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
//fetch_demographics();
save_survey(0);
return "You have spent "+Math.ceil(t)+ " minute/s on the survey!";
//!!delete last inserted element if not quit
}
</script>
I have checked whether those functions have any problem but they work fine when I call them from different part of the code. Later, I thought it might be because of unreachable function scope but its not the case. I have tried moving the onbeforeunload() at the end of script and the problem still persists. Wondering why this is happening, can anyone enlighten me?
I identified where the problem was. I am using json_encode instead of JSON.stringify and hence it is crashing(which I found and changed already in sf=1 case). That tip with debugger is invaluable. Also, its working fine even without async: false.
Thank you again #AdrianoRepetti!

fetching xml data into a div via ajax and javascript

Building a chat app and I am trying to fetch all logged in user into a div with ID name "chat_members". But nothing shows up in the div and I have verified that the xml file structure is correct but the javascript i'm using alongside ajax isn't just working.
I think the problem is around the area of the code where I'm trying to spool out the xml data in the for loop.
XML data sample:
<member>
<user id="1">Ken Sam</user>
<user id="2">Andy James</user>
</member>
Javascript
<script language="javascript">
// JavaScript Document
var getMember = XmlHttpRequestObject();
var lastMsg = 0;
var mTimer;
function startChat() {
getOnlineMembers();
}
// Checking if XMLHttpRequest object exist in user browser
function XmlHttpRequestObject(){
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}
else if(window.ActiveXObject){
return new ActiveXObject("Microsoft.XMLHTTP");
} else{
//alert("Status: Unable to launch Chat Object. Consider upgrading your browser.");
document.getElementById("ajax_status").innerHTML = "Status: Unable to launch Chat Object. Consider upgrading your browser.";
}
}
function getOnlineMembers(){
if(getMember.readyState == 4 || getMember.readyState == 0){
getMember.open("GET", "get_chat.php?get_member", true);
getMember.onreadystatechange = memberReceivedHandler;
getMember.send(null);
}else{
// if the connection is busy, try again after one second
setTimeout('getOnlineMembers()', 1000);
}
}
function memberReceivedHandler(){
if(getMember.readyState == 4){
if(getMember.status == 200){
var chat_members_div = document.getElementById('chat_members');
var xmldoc = getMember.responseXML;
var members_nodes = xmldoc.getElementsByTagName("member");
var n_members = members_nodes.length;
for (i = 0; i < n_members; i++) {
chat_members_div.innerHTML += '<p>' + members_nodes[i].childNodes.nodeValue + '</p>';
chat_members_div.scrollTop = chat_members_div.scrollHeight;
}
mTimer = setTimeout('getOnlineMembers();',2000); //Refresh our chat members in 2 seconds
}
}
}
</script>
HTML page
<body onLoad="javascript:startChat();">
<!--- START: Div displaying all online members --->
<div id="chat_members">
</div>
<!---END: Div displaying all online members --->
</body>
I'm new to ajax and would really appreciate getting help with this.
Thanks!
To troubleshoot this:
-- Use an HTTP analyzer like HTTP Fiddler. Take a look at the communication -- is your page calling the server and getting the code that you want back, correctly, and not some type of HTTP error?
-- Check your IF statements, and make sure they're bracketed correctly. When I see:
if(getMember.readyState == 4 || getMember.readyState == 0){
I see confusion. It should be:
if( (getMember.readyState == 4) || (getMember.readyState == 0)){
It might not make a difference, but it's good to be absolutely sure.
-- Put some kind of check in your javascript clauses after the IF to make sure program flow is executing properly. If you don't have a debugger, just stick an alert box in there.
You must send the xmlhttp request before checking the response status:
function getOnlineMembers(){
getMember.open("GET", "get_chat.php?get_member", true);
getMember.onreadystatechange = memberReceivedHandler;
getMember.timeout = 1000; //set timeout for xmlhttp request
getMember.ontimeout = memberTimeoutHandler;
getMember.send(null);
}
function memberTimeoutHandler(){
getMember.abort(); //abort the timedout xmlhttprequest
setTimeout(function(){getOnlineMembers()}, 2000);
}
function memberReceivedHandler(){
if(getMember.readyState == 4 && getMember.status == 200){
var chat_members_div = document.getElementById('chat_members');
var xmldoc = getMember.responseXML;
var members_nodes = xmldoc.documentElement.getElementsByTagName("member");
var n_members = members_nodes.length;
for (i = 0; i < n_members; i++) {
chat_members_div.innerHTML += '<p>' + members_nodes[i].childNodes.nodeValue + '</p>';
chat_members_div.scrollTop = chat_members_div.scrollHeight;
}
mTimer = setTimeout('getOnlineMembers();',2000); //Refresh our chat members in 2 seconds
}
}
To prevent caching response you can try:
getMember.open("GET", "get_chat.php?get_member&t=" + Math.random(), true);
Check the responseXML is not empty by:
console.log(responseXML);
Also you might need to select the root node of the xml response before selecting childNodes:
var members_nodes = xmldoc.documentElement.getElementsByTagName("member"); //documentElement selects the root node of the xml document
hope this helps

JavaScript EventSource SSE not firing in browser

I have been developing a nodejs server to provide server-side-events for a new website I am developing in HTML5.
When I telnet to the server it works correctly, sending me the required HTTP response headers followed by a stream of events that i am presently generating every 2 or 3 seconds just to prove it works.
I have tried the latest version of FireFox, Chrome and Opera and they create the EventSource object and connect to the nodejs server OK but none of the browsers generate any of the events, including the onopen, onmessage and onerror.
However, if I stop my nodejs server, terminating the connection from the browsers, they all suddenly dispatch all the messages and all my events are shown. The browsers then all try to reconnect to the server as per spec.
I am hosting everything on a webserver. nothing is running in local files.
I have read everything I can find online, including books I've purchased and nothing indicates any such problem. Is there something Im missing?
A sample server implementation
var http = require('http');
var requests = [];
var server = http.Server(function(req, res) {
var clientIP = req.socket.remoteAddress;
var clientPort = req.socket.remotePort;
res.on('close', function() {
console.log("client " + clientIP + ":" + clientPort + " died");
for(var i=requests.length -1; i>=0; i--) {
if ((requests[i].ip == clientIP) && (requests[i].port == clientPort)) {
requests.splice(i, 1);
}
}
});
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'});
requests.push({ip:clientIP, port:clientPort, res:res});
res.write(": connected.\n\n");
});
server.listen(8080);
setInterval(function test() {
broadcast('poll', "test message");
}, 2000);
function broadcast(rtype, msg) {
var lines = msg.split("\n");
for(var i=requests.length -1; i>=0; i--) {
requests[i].res.write("event: " + rtype + "\n");
for(var j=0; j<lines.length; j++) {
if (lines[j]) {
requests[i].res.write("data: " + lines[j] + "\n");
}
}
requests[i].res.write("\n");
}
}
A sample html page
<!DOCTYPE html>
<html>
<head>
<title>SSE Test</title>
<meta charset="utf-8" />
<script language="JavaScript">
function init() {
if(typeof(EventSource)!=="undefined") {
var log = document.getElementById('log');
if (log) {
log.innerHTML = "EventSource() testing begins..<br>";
}
var svrEvents = new EventSource('/sse');
svrEvents.onopen = function() {
connectionOpen(true);
}
svrEvents.onerror = function() {
connectionOpen(false);
}
svrEvents.addEventListener('poll', displayPoll, false); // display multi choice and send back answer
svrEvents.onmessage = function(event) {
var log = document.getElementById('log');
if (log) {
log.innerHTML += 'message: ' + event.data + "<br>";
}
// absorb any other messages
}
} else {
var log = document.getElementById('log');
if (log) {
log.innerHTML = "EventSource() not supported<br>";
}
}
}
function connectionOpen(status) {
var log = document.getElementById('log');
if (log) {
log.innerHTML += 'connected: ' + status + "<br>";
}
}
function displayPoll(event) {
var html = event.data;
var log = document.getElementById('log');
if (log) {
log.innerHTML += 'poll: ' + html + "<br>";
}
}
</script>
</head>
<body onLoad="init()">
<div id="log">testing...</div>
</body>
</html>
These examples are basic but of the same variety as every other demo i've seen in books and online. The eventSource only seems to be working if I end a client connection or terminate the server but this would be polling instead of SSE and I particularly want to use SSE.
Interestingly, demos, such as thouse from html5rock also seem to not quite work as expected when I use them online..
cracked it! :)
Thanks to some help from Tom Kersten who helped me with testing. Turns out the code isnt the problem.
Be warned.. if your client uses any kind of anti-virus software which intercepts web requests, it may cause problems here. In this case, Sophos Endpoint Security, which provides enterprise grade anti-virus and firewall protection has a feature called web protection. Within this features is an option to scan downloads; it seems that the SSE connection is treated as a download and thus not released to the browser until the connection is closed and the stream received to scan. Disabling this option cures the problem. I have submitted a bug report but other anti-virus systems may do the same.
thanks for your suggestions and help everyone :)
http://www.w3.org/TR/eventsource/#parsing-an-event-stream
Since connections established to remote servers for such resources are
expected to be long-lived, UAs should ensure that appropriate
buffering is used. In particular, while line buffering with lines are
defined to end with a single U+000A LINE FEED (LF) character is safe,
block buffering or line buffering with different expected line endings
can cause delays in event dispatch.
Try to play with line endings ("\r\n" instead of "\n").
http://www.w3.org/TR/eventsource/#notes
Authors are also cautioned that HTTP chunking can have unexpected
negative effects on the reliability of this protocol. Where possible,
chunking should be disabled for serving event streams unless the rate
of messages is high enough for this not to matter.
I modified your server-side script, which 'seems' partly works for Chrome.
But the connection break for every 2 broadcast & only 1 can be shown on client.
Firefox works for 1st broadcast and stop by this error:
Error: The connection to /sse was interrupted while the page was loading.
And Chrome will try to reconnect and received 3rd broadcast.
I think it's related to firewall setting too but can't explain why sometime will works.
Note: For event listener of response (line 10), 'close' & 'end' have different result,
You can try it and my result is [close: 1 success/2 broadcast] & [end: 1 success/8 broadcast]
var http = require('http'), fs = require('fs'), requests = [];
var server = http.Server(function(req, res) {
var clientIP = req.socket.remoteAddress;
var clientPort = req.socket.remotePort;
if (req.url == '/sse') {
var allClient="";for(var i=0;i<requests.length;i++){allClient+=requests[i].ip+":"+requests[i].port+";";}
if(allClient.indexOf(clientIP+":"+clientPort)<0){
requests.push({ip:clientIP, port:clientPort, res:res});
res.on('close', function() {
console.log("client " + clientIP + ":" + clientPort + " died");
for(var i=requests.length -1; i>=0; i--) {
if ((requests[i].ip == clientIP) && (requests[i].port == clientPort)) {
requests.splice(i, 1);
}
}
});
}
}else{
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(fs.readFileSync('./test.html'));
res.end();
}
});
server.listen(80);
setInterval(function test() {
broadcast('poll', "test message");
}, 500);
var broadcastCount=0;
function broadcast(rtype, msg) {
if(!requests.length)return;
broadcastCount++;
var lines = msg.split("\n");
for(var i = requests.length - 1; i >= 0; i--) {
requests[i].res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
requests[i].res.write("event: " + rtype + "\n");
for(var j = 0; j < lines.length; j++) {
if(lines[j]) {
requests[i].res.write("data: " + lines[j] + "\n");
}
}
requests[i].res.write("data: Count\: " + broadcastCount + "\n");
requests[i].res.write("\n");
}
console.log("Broadcasted " + broadcastCount + " times to " + requests.length + " user(s).");
}

Categories

Resources