What am I doing wrong with Chrome's FileSystem API? - html

Trying to use Chrome's API here (nothing fancy, just want to get the permission box up at least) and no matter what example I find I seem to run into problems.
For example this github link here.. Now pretty much all of these examples are so old that the language is different now. RequestFileSystem is Chrome specific now with webkitRequestFileSystem and FileError has been replaced by DOMError. Here's the relevant javascript, with those parts swapped out to their modern equivalents:
window.webkitRequestFileSystem = window.webkitRequestFileSystem || window.webkitRequestFileSystem;
// Handle errors
function errorHandler(e) {
var msg = '';
switch (e.code) {
case DOMError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case DOMError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
break;
case DOMError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case DOMError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case DOMError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = 'Unknown Error';
break;
};
console.log('Error: ' + msg);
}
// Init and write some data to a file
function onInitFs(fs) {
fs.root.getFile('log-f-api.txt', {create: true}, function(fileEntry) {
fileEntry.isFile === true;
fileEntry.name == 'log-f-api.txt';
fileEntry.fullPath == '/log-f-api.txt';
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e);
};
// Create a new Blob and write it to log.txt.
if (!window.BlobBuilder && window.WebKitBlobBuilder)
window.BlobBuilder = window.WebKitBlobBuilder; // in Chrome 12.
var bb = new BlobBuilder();
bb.append("some stuff");
console.log("bb size:"+bb.size);
bb.append('put some nice text in our file....');
var ourData = bb.getBlob('text/plain');
fileWriter.write(ourData);
}, errorHandler);
}, errorHandler);
}
// start the party
$(function() {
document.getElementById('hello').innerHTML = 'start the tests';
window.webkitRequestFileSystem(window.PERSISTENT, 5*1024*1024, onInitFs,errorHandler);
});
I've tried out a few different examples and no matter what I just "Error: Unknown Error" in console... I know that Chrome won't allow this API over file://, using both Apache over localhost as well as hosting it on a test server produces the same result. Everything I can find says it should work in Chrome 66, the version I'm trying to get this to work on. What am I doing wrong here?

Related

Calling window.webkitRequestFileSystem twice causes first call not to be bypassed

Have an interesting problem ... I am making a BB10 application (I know) and am using the window.webkitRequestFileSystem call to a) provide a list of local files that this application has downloaded and b) read one of those files and display the contents - nothing crazy.
Individually, I can get both calls a) and b) to work; however, when I place them in the same function hoping to both display a list of files and read one of them, it causes the reading one not to fire at all.
In the example below, regardless of whether the listing call comes before or after the reading call, the reading call will not fire, i.e., I will never see the 'fileentry' alert.
What's going on?
function initFS(){
sharedFolder = blackberry.io.sharedFolder;
var path = sharedFolder+'/downloads';
//alert(path);
document.getElementById('plancontents').value="initialized";
window.requestFileSystem = window.requestFileSystem ||
window.webkitRequestFileSystem;
//window.requestFileSystem(window.TEMPORARY, 1024 * 1024,
//window.requestFileSystem(LocalFileSystem.PERSISTENT, 1024*1024*5,
window.webkitRequestFileSystem(window.PERSISTENT, 1024*1024*5,
function (fs) {
//fs.root.getFile(blackberry.io.sharedFolder
//fs.root.getFile('file:///accounts/1000/shared/downloads/filename.xml', {create: false},
fs.root.getFile(sharedFolder+'/downloads/filename.xml', {create: false},
function (fileEntry) {
alert("fileentry");
fileEntry.file(function (file) {
var reader = new FileReader();
//alert("trying to read file");
reader.onloadend = function (e) {
document.getElementById('plancontents').value = this.result;
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
});
window.webkitRequestFileSystem(window.PERSISTENT, 1024*1024*5,
function (fs) {
alert('FS requested and inside');
fs.root.getDirectory(path, {}, function(dirEntry){
alert('inside getDir');
var dirReader = dirEntry.createReader();
alert('created reader');
dirReader.readEntries(function(entries) {
alert('trying to list dir');
for(var i = 0; i < entries.length; i++) {
var entry = entries[i];
if (entry.isDirectory) {
alert('Directory: ' + entry.fullPath);
}
else if (entry.isFile) {
alert('File: ' + entry.fullPath);
}
}
}, errorHandler);
}, errorHandler);
});
}

WebRTC SDP object (local description) by Firefox does not contain DataChannel info unlike Chrome?

I'm testing WebRTC procedure step by step for my sake.
I wrote some testing site for server-less WebRTC.
http://webrtcdevelop.appspot.com/
In fact, STUN server by google is used, but no signalling server deployed.
Session Description Protocol (SDP) is exchanged manually by hand that is CopyPaste between browser windows.
So far, here is the result I've got with the code:
'use strict';
var peerCon;
var ch;
$(document)
.ready(function()
{
init();
$('#remotebtn2')
.attr("disabled", "");
$('#localbtn')
.click(function()
{
offerCreate();
$('#localbtn')
.attr("disabled", "");
$('#remotebtn')
.attr("disabled", "");
$('#remotebtn2')
.removeAttr("disabled");
});
$('#remotebtn')
.click(function()
{
answerCreate(
new RTCSessionDescription(JSON.parse($('#remote')
.val())));
$('#localbtn')
.attr("disabled", "");
$('#remotebtn')
.attr("disabled", "");
$('#remotebtn')
.attr("disabled", "");
});
$('#remotebtn2')
.click(function()
{
answerGet(
new RTCSessionDescription(JSON.parse($('#remote')
.val())));
$('#remotebtn2')
.attr("disabled", "");
});
$('#msgbtn')
.click(function()
{
msgSend($('#msg')
.val());
});
});
var init = function()
{
//offer------
peerCon =
new RTCPeerConnection(
{
"iceServers": [
{
"url": "stun:stun.l.google.com:19302"
}]
},
{
"optional": []
});
var localDescriptionOut = function()
{
console.log(JSON.stringify(peerCon.localDescription));
$('#local')
.text(JSON.stringify(peerCon.localDescription));
};
peerCon.onicecandidate = function(e)
{
console.log(e);
if (e.candidate === null)
{
console.log('candidate empty!');
localDescriptionOut();
}
};
ch = peerCon.createDataChannel(
'ch1',
{
reliable: true
});
ch.onopen = function()
{
dlog('ch.onopen');
};
ch.onmessage = function(e)
{
dlog(e.data);
};
ch.onclose = function(e)
{
dlog('closed');
};
ch.onerror = function(e)
{
dlog('error');
};
};
var msgSend = function(msg)
{
ch.send(msg);
}
var offerCreate = function()
{
peerCon
.createOffer(function(description)
{
peerCon
.setLocalDescription(description, function()
{
//wait for complete of peerCon.onicecandidate
}, error);
}, error);
};
var answerCreate = function(descreption)
{
peerCon
.setRemoteDescription(descreption, function()
{
peerCon
.createAnswer(
function(description)
{
peerCon
.setLocalDescription(description, function()
{
//wait for complete of peerCon.onicecandidate
}, error);
}, error);
}, error);
};
var answerGet = function(description)
{
peerCon.setRemoteDescription(description, function()
{ //
console.log(JSON.stringify(description));
dlog('local-remote-setDescriptions complete!');
}, error);
};
var error = function(e)
{
console.log(e);
};
var dlog = function(msg)
{
var content = $('#onmsg')
.html();
$('#onmsg')
.html(content + msg + '<br>');
}
Firefox(26.0):
RtpDataChannels
onopen event is fired successfully, but send fails.
Chrome(31.0):
RtpDataChannels
onopen event is fired successfully, and send also succeeded.
A SDP object by Chrome is as follows:
{"sdp":".................. cname:L5dftYw3P3clhLve
\r\
na=ssrc:2410443476 msid:ch1 ch1
\r\
na=ssrc:2410443476 mslabel:ch1
\r\
na=ssrc:2410443476 label:ch1
\r\n","type":"offer"}
where the ch1 information defined in the code;
ch = peerCon.createDataChannel(
'ch1',
{
reliable: false
});
is bundled properly.
However, a SDP object (local description) by Firefox does not contain DataChannel at all, and moreover, the SDP is much shorter than Chrome, and less information bundled.
What do I miss?
Probably, I guess the reason that send fails on DataChannel is due to this lack of information in the SDP object by firefox.
How could I fix this?
I investigated sources of various working libraries, such as peerJS, easyRTC, simpleWebRTC, but cannot figure out the reason.
Any suggestion and recommendation to read is appreciated.
[not an answer, yet]
I leave this here just trying to help you. I am not much of a WebRTC developer. But, curious i am, this quite new and verry interresting for me.
Have you seen this ?
DataChannels
Supported in Firefox today, you can use DataChannels to send peer-to-peer
information during an audio/video call. There is
currently a bug that requires developers to set up some sort of
audio/video stream (even a “fake” one) in order to initiate a
DataChannel, but we will soon be fixing that.
Also, i found this bug hook, witch seems to be related.
One last point, your version of adapter.js is different from the one served on code.google. And .. alot. the webrtcDetectedVersion part is missing in yours.
https://code.google.com/p/webrtc/source/browse/stable/samples/js/base/adapter.js
Try that, come back to me with good newz. ?
After last updating, i have this line in console after clicking 'get answer'
Object { name="INVALID_STATE", message="Cannot set remote offer in
state HAVE_LOCAL_OFFER", exposedProps={...}, more...}
but this might be useless info ence i copy pasted the same browser offre to answer.
.. witch made me notice you are using jQuery v1.7.1 jquery.com.
Try updating jQuery (before i kill a kitten), and in the meantime, try make sure you use all updated versions of scripts.
Woups, after fast reading this : https://developer.mozilla.org/en-US/docs/Web/Guide/API/WebRTC/WebRTC_basics then comparing your javascripts, i see no SHIM.
Shims
As you can imagine, with such an early API, you must use the browser
prefixes and shim it to a common variable.
> var PeerConnection = window.mozRTCPeerConnection ||
> window.webkitRTCPeerConnection; var IceCandidate =
> window.mozRTCIceCandidate || window.RTCIceCandidate; var
> SessionDescription = window.mozRTCSessionDescription ||
> window.RTCSessionDescription; navigator.getUserMedia =
> navigator.getUserMedia || navigator.mozGetUserMedia ||
> navigator.webkitGetUserMedia;

Recommended practice for application exception handling in AngularJS

I am currently exploring possible methods to handle application-wide exceptions in AngularJS.
One of the things we really wanted to avoid was wrapping multiple parts of the application in nested try/catch blocks, but handle things cleanly - i.e throw an exception in response to a promise.
Has anyone covered this issue before and have any recommendations?
Any suggestions on how to pick up exceptions in services as well as controllers/directives. (See below - broadcast works ok, but only if you can attach a listener to a scope).
Progress so far
A few short design goals:
Allow exceptions from one part of the application to be handled elsewhere - or possibly multiple places (i.e. 'display error notification to user', 'disable widget').
Provide central management of common error conditions - i.e. log to server, display notification to user, redirect to login.
Allow exceptions to be thrown from controllers, directives, services etc.
Eventually allow localized messages.
The current leaning of my team is to write a service to handle exceptions, which would expose a range of simple calls:
exceptionService.warn('exception_token');
exceptionService.crit('another_exception_token');
This service would then format an 'exception' object and broadcast this from the rootscope. This would allow a default handler to watch for any broadcasts and apply default actions, as well as allow custom listeners to be set in others scopes, which could handle more specific conditions - i.e. disable a part of the UI.
var exception = {
token: 'exception_token',
severity': 'crit'
};
// broadcast exception
$rootScope.$broadcast(
'application_exception',
exception
);
I was thinking about the same recently, and it occurred to me that when it comes to a good error handling in javascript, it is irrelevant which framework you are using, Angular on something else. I wrote one such error handler recently for an AngularJS project, but I did it in a way it can be used in any framework.
Here's the complete code. You can either use it directly, or modify to your needs...
/*
Factory errorFact is to simplify error handling and reporting in other objects.
It supports detailed error output as a text string and into the browser's console.
Usage example:
A function that supports return of an error object would have the following declaration
as its very first line:
var e = errorFact.create("objectName.funcName", arguments);
- in this declaration we specify the full object + method name as the first string parameter,
- and as the second parameter we pass javascript's reserved variable called arguments, which
provides reference to all of the function's parameters for logging.
When an error occurs, the function would return:
return e.error("Error description text");
- this line will create and return a complete error context.
When a function that supports return of an error object makes a call into another
function that also supports the error context, then it can return the nested error
result by passing the embedded error to the current error object instead of the error
text.
Example:
var e = errorFact.create("objectName.funcName", arguments);
var data = callAnotherFunc(...); // calling a function that support an error object;
if(data.isError){ // If an error was triggered;
return e.error(data); // return that error from the current context;
}
The top-level code that calls an error-returning function would do verification
and if an error occurred, log all its details into console (typically).
Example:
var data = getData(...);
if(data.isError){
data.log(); // Output all the error details into the browser's console;
}
*/
"use strict";
app.factory("errorFact", function(){
return {
// creates a new error context;
create: function(method, args){
var result = {
// initiates and returns the error context;
error: function(msg){
this.info.isError = true;
if(msg.isError){
this.info.details.caller = msg;
}else{
this.info.details.msg = msg;
}
return this.info;
},
info:
{
isError: false,
details: {},
log: function(){
if(this.isError){
console.error(this.format());
}
},
// formats complete error details into a text string;
format: function(){
if(this.details.caller){
var txt = this.details.caller.format();
txt += "\nCALLER: " + this.details.method + "(" + this.formatArguments() + ")";
return txt;
}
if(this.details.method){
return "Error calling " + this.details.method + "(" + this.formatArguments() + "): " + this.details.msg;
}else{
return this.details.msg;
}
return "";
},
// formats function argument details into a text string;
formatArguments: function(){
if(!this.details.args){
return "";
}
var params = "";
for(var i = 0;i < this.details.args.length;i ++){
if(params.length > 0){
params += ",";
}
var p = this.details.args[i];
if(p === undefined){
params += "undefined";
}else{
if(p === null){
params += "null";
}else{
if(typeof(p) == "object"){
params += "Object";
}else{
params += p;
}
}
}
}
return params;
}
}
};
if(method){
result.info.details.method = method;
}
if(args){
result.info.details.args = args;
}
return result;
}
}
});
Below is a factory that shows how it is used:
"use strict";
app.factory('moduleFact', ['errorFact', function(errorFact){
return {
// Locates existing module and expands its key Id references
// into corresponding object references:
// - If 'hintGroupId' is present, property 'hints' is added from
// the corresponding hint group.
// - If 'repModules' is present, properties 'question' and 'refs'
// are added.
// On success, return the expanded module object.
// On failure, returns an error object.
//
// NOTE: Currently supports only the first value in repModules.
expandModule: function(moduleData, moduleId){
var e = errorFact.create("moduleFact.expandModule", arguments);
if(!moduleData || !moduleData.modules || !moduleId){
return e.error("Invalid parameters passed");
}
var mod = this.findModule(moduleData, moduleId);
if(mod.isError){
return e.error(mod);
}
var src = mod;
if(mod.repModules){
var repId = mod.repModules[0];
if(!repId){
return e.error("Invalid repModules encountered");
}
///////////////////////////////////////
// temporary check to throw a warning:
if(mod.repModules.length > 1){
console.warn("Multiple values in property repModules: " + JSON.stringify(mod.repModules) +
", which is not supported yet (only the first value is used)");
}
///////////////////////////////////////
src = this.findModule(moduleData, repId);
if(src.isError){
return e.error(src);
}
}
if(src.question){
mod.question = src.question;
}else{
return e.error("Question not specified");
}
if(src.refs){
mod.refs = src.refs;
}
if(src.hintGroupId){
var hg = this.findHintGroup(moduleData, src.hintGroupId);
if(hg.isError){
return e.error(hg);
}
mod.hints = hg.hints;
}
return mod; // needed extra: expand attribute repModules
},
// Expands all the modules and returns the data;
expandAllModules: function(moduleData){
var e = errorFact.create("moduleFact.expandAllModules", arguments);
if(!moduleData || !moduleData.modules){
return e.error("Invalid parameters passed");
}
for(var i = 0;i < moduleData.modules.length;i ++){
var result = this.expandModule(moduleData, moduleData.modules[i].id);
if(result.isError){
return e.error(result);
}
}
return moduleData;
},
// Locates and returns module by its Id;
findModule: function(moduleData, moduleId){
var e = errorFact.create("moduleFact.findModule", arguments);
if(!moduleData || !moduleData.modules || !moduleId){
return e.error("Invalid parameters passed");
}
for(var i = 0;i < moduleData.modules.length;i ++){
if(moduleData.modules[i].id == moduleId){
return moduleData.modules[i];
}
}
return e.error("Module with Id = " + moduleId + " not found");
},
// Locates and returns Hint Group by its Id;
findHintGroup: function(moduleData, hintGroupId){
var e = errorFact.create("moduleFact.findHintGroup", arguments);
if(!moduleData || !moduleData.hintGroups || !hintGroupId){
return e.error("Invalid parameters passed");
}
for(var i = 0;i < moduleData.hintGroups.length;i ++){
if(moduleData.hintGroups[i].id == hintGroupId){
return moduleData.hintGroups[i];
}
}
return e.error("Hint Group with Id = " + hintGroupId + " not found");
}
}
}]);
So, when you have such factory in place, your high-level code, such as in a controller would just log any issues as shown in the example below:
"use strict";
app.controller('standardsCtrl', ['$scope', 'moduleFact', function($scope, moduleFact){
var data = ...//getting data;
var mod = moduleFact.expandAllModules(data);
if(mod.isError){
mod.log(); // log all error details into the console;
}else{
// use the data
}
});
}]);
You can override the $exceptionHandler in order to pass the exceptions to your own central service for exceptions, but the $exceptionHandler seems to only receive the exceptions thrown from your controllers, directives, etc... but not for the exceptions originated from ajax calls. For those exceptions you can implement an interceptor like the one described in this page:
EDITED: Link is dead permanently.
Archive.org link
whats your opinion to create a centralized error handling function for your app
so whenever an error happened with your frontend tear (angular, API calls,...) it executed, so no need to write your error handling every time
so here is my code
(function () {
'use strict';
angular
.module('app')
.factory('$exceptionHandler', ExceptionHandler);
ExceptionHandler.$inject = ['$injector']; //for minification
function ExceptionHandler($injector) {
var $log, sweetAlert, $translate;
return function exceptionHandler(exception, cause) {
// Add DI here to prevent circular dependency
$log = $log || $injector.get('$log');
sweetAlert = sweetAlert || $injector.get('sweetAlert'); //19degrees.ngSweetAlert2
$translate = $translate || $injector.get('$translate');
// $loggerService = $loggerService || $injector.get('$loggerService');
var title, message;
title = $translate.instant('General error title');
message = $translate.instant('General error message', { exceptionMessage: exception.message });
sweetAlert.error(title, message);
$log.error(exception, cause);
// loggerService.logErrorsToBackend(exception, cause);
};
}
})();
I'm not sure if this approach considered to be a best practice but hope it helps you.

Chrome Extension crashes with "bad extension message webRequestInternal.eventHandled"

I have a chrome extension that out of nowhere crashes, so I saw that you could debug your chrome by activating the logging, so that's what I did, and I noticed that before the crash happens, it's thrown an error of: " bad extension message webRequestInternal.eventHandled : terminating renderer.", so maybe this error occur in one of webRequests listeners. But I don't know what to do anymore to make it right.
This is the log error that happens before the function closes:
[1888:3844:17965500:ERROR:extension_function.cc(143)] bad extension message webRequestInternal.eventHandled : terminating renderer.
[1888:3844:17965625:VERBOSE1:web_request_time_tracker.cc(181)] WR percent 2643: http://mypage.com/test: = 0.985185
[1888:3844:17965625:VERBOSE1:web_request_time_tracker.cc(181)] WR percent 2644: http://mypage.com/test: 123/123 = 1
[1888:3464:17965734:VERBOSE1:speech_input_extension_manager.cc(228)] Extension unloaded. Requesting to enforce stop...
I have 2 webRequest listeners:
The OnBeforeRequest Page blocking:
chrome.webRequest.onBeforeRequest.addListener(blockURLs,
{urls: ["http://*\/*", "https://*\/*"]}, //I have to use all because I use specific page filters
["blocking"]
);
function blockURLs(details){
var url = details.url.split('/');
if(STRING_OF_SERVERS.indexOf(url[2]) < 0 || details.url.indexOf('.css') > -1 )
return {cancel: true};
}
And the onBeforeSendHeaders (This is probably the one erroneous):
chrome.webRequest.onBeforeSendHeaders.addListener(
function(details) {
var cookie_found = false;
for (var i = 0; i < details.requestHeaders.length; ++i) {
if (details.requestHeaders[i].name === 'Cookie') {
//details.requestHeaders.splice(i,1); //,localStorage['COOKIES']
//alert("ADDED: " + localStorage['COOKIES']);
if(window['SERVIDOR_TEMP_DATA_' + SERVER_INDEX]['COOKIES'] != ''){
details.requestHeaders[i] = new Object();
details.requestHeaders[i].name = 'Cookie';
details.requestHeaders[i].value = window['SERVIDOR_TEMP_DATA_' + SERVER_INDEX]['COOKIES'];
}else{
window['SERVIDOR_TEMP_DATA_' + SERVER_INDEX]['COOKIES'] = details.requestHeaders[i].value;
cookie_found = true;
break;
}
}
if(cookie_found == false && window['SERVIDOR_TEMP_DATA_' + SERVER_INDEX]['COOKIES'] != ''){
var i = details.requestHeaders.length;
details.requestHeaders[i] = new Object();
details.requestHeaders[i].name = 'Cookie';
details.requestHeaders[i].value = window['SERVIDOR_TEMP_DATA_' + SERVER_INDEX]['COOKIES'];
}
//console.log(details.url);
//console.log(details.requestHeaders);
return {requestHeaders: details.requestHeaders};
},
{urls: URLS_TYPE, types : ["main_frame", "sub_frame", "xmlhttprequest", "object", "stylesheet", "script", "image", "other"]},
["blocking", "requestHeaders"]);
//StartClicking();
});
The variables not specified:
*var URLS_TYPE is an array of Sites allowed
*var STRING_OF_SERVERS is a String containing all the possible combination of sites that are allowed
And in my application I make a lot of web requests, and I don't know what to do anymore :/
What could possibly be throwing this crash?
Thanks in advance.
I was able to find the answer.
the problem is that if the Request Headers come missing any information required , it just crashes instead of reporting an error.
My details.requestHeader was returning a cookie that only has a name and no value attribute, so If I added the value attribute the crash would go away.
Cookie object is supposed to come like this:
{ name: "key", value: "val"}
and I was generating only {name: "key"} since I was adding an undefined value, After I used JSON.Stringify(details.requestHeaders) I could see that it was missing and now problem solved.
I just had to make sure the cookie value wasn't undefined, if it was just add a empty string or whatever you want.

Multiplayer HTML5, Node.js, Socket.IO

I trying create simple Multi-player with HTML5 Canvas, JavaScript(too using John Resig simple Inheritance library) and Node.js with Socket.IO.
My client code:
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
var socket = new io.Socket('127.0.0.1', {port: 8080});
var player = null;
var UP = 'UP',
LEFT = 'LEFT',
DOWN = 'DOWN',
RIGHT = 'RIGHT';
socket.connect();
socket.on('connect', function() {socket.send();
console.log('Connected!');
player = new Player(50, 50);
});
socket.on('message', function(msg) {
if(msg == 'UP') {
player.moveUP();
} else if(msg == 'LEFT') {
player.moveLEFT();
} else if(msg == 'DOWN') {
player.moveDOWN();
} else if(msg == 'RIGHT') {
player.moveRIGHT();
} else {
}
});
socket.on('disconnect', function() {
console.log('Disconnected!');
});
var Player = Class.extend({
init : function(x, y) {
this.x = x;
this.y = y;
},
setX : function(x){
this.x = x;
},
getX : function(){
return this.x;
},
setY : function(y){
this.y = y;
},
getY : function(){
return this.y;
},
draw : function(){
context.clearRect(0, 0, 350, 150);
context.fillRect(this.x, this.y, 15, 15);
},
move : function() {
this.x += 1;
this.y += 1;
},
moveUP : function() {
this.y--;
},
moveLEFT : function() {
this.x--;
},
moveDOWN : function() {
this.y++;
},
moveRIGHT : function() {
this.x++;
}
});
function checkKeyCode(event) {
var keyCode;
if(event == null) {
keyCode = window.event.keyCode;
} else {
keyCode = event.keyCode;
}
switch(keyCode) {
case 38: // UP
player.moveUP();
socket.send(UP);
break;
case 37: // LEFT
player.moveLEFT();
socket.send(LEFT);
break;
case 40: //DOWN
player.moveDOWN();
socket.send(DOWN);
break;
case 39: // RIGHT
player.moveRIGHT();
socket.send(RIGHT);
break;
default:
break;
}
}
function update() {
player.draw();
}
var FPS = 30;
setInterval(function() {
update();
player.draw();
}, 1000/FPS);
function init() {
document.onkeydown = checkKeyCode;
}
init();
And server code:
var http = require('http'),
io = require('socket.io'),
buffer = new Array(),
server = http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<h1>Hello world</h1>');
});
server.listen(8080);
var socket = io.listen(server);
socket.on('connection', function(client){
client.on('message', function(message){
console.log(message);
client.broadcast(message);
})
client.on('disconnect', function(){
})
});
And when I run two client's I with first client can move second client Rect and with second client move first client rect and something like with third client can move first and second client rect's.
I have question how to create real Multi-Player? something like:
Open three client's and first client get rect1, second rect2 and last rect3. First client only can move rect1, client third can move only rect3.
Maybe anyone have idea? I search in Google but don't find answer.
Sorry for my English language.
First, check out http://www.google.com/events/io/2011/sessions/super-browser-2-turbo-hd-remix-introduction-to-html5-game-development.html
it explains how to use requestAnimationFrame among other things.
Second, the game state should exist on the server and be mirrored on the clients.
When a player clicks down, the client should only send a message. The server should then send a message to all the clients, including the client that took the action.
Each player should exist as an object on the server. When a player logs in they should be brought up to date about the status of each player already on the server.
modified client code: http://codr.cc/s/d0154536/js
modified server code: http://codr.cc/s/f96ce1d2/js
Glenn Fiedler's What every programmer needs to know about game networking -article is good read for anyone who wants get into game networking. It explains the basics in very high level so that it is adaptable for JS and Socket.io.
In case anyone stumbles across this question as I have just now, I wanted to add this link as an example.
I was following the same path as the op several months ago and read every article I could find on the authoritative server model (including the one referenced in the answer by #Epeli), and how to implement it with nodejs/socketio.
The result of my research manifested itself in the github project located at the link provided above (there is also a live demo). Hope this helps someone.
There is now an open-source multiplayer realtime javascript server (and client library) called Lance.gg, which provides, as you say,
a real multiplayer experience
It handles client-side prediction, step drift, bending, and basic physics.
Disclaimer: I am one of the contributors