Our web application has a feature which uses Flash (AS3) to take photos using the user's web cam, then passes the resulting byte array to PHP where it is reconstructed and saved on the server.
However, we need to be able to take this web application offline, and we have chosen Gears to do so. The user takes the app offline, performs his tasks, then when he's reconnected to the server, we "sync" the data back with our central database.
We don't have PHP to interact with Flash anymore, but we still need to allow users to take and save photos. We don't know how to save a JPG that Flash creates in a local database. Our hope was that we could save the byte array, a serialized string, or somehow actually persist the object itself, then pass it back to either PHP or Flash (and then PHP) to recreate the JPG.
We have tried:
- passing the byte array to Javascript instead of PHP, but javascript doesn't seem to be able to do anything with it (the object seems to be stripped of its methods)
- stringifying the byte array in Flash, and then passing it to Javascript, but we always get the same string:
ÿØÿà
Now we are thinking of serializing the string in Flash, passing it to Javascript, then on the return route, passing that string back to Flash which will then pass it to PHP to be reconstructed as a JPG. (whew). Since no one on our team has extensive Flash background, we're a bit lost.
Is serialization the way to go? Is there a more realistic way to do this? Does anyone have any experience with this sort of thing? Perhaps we can build a javascript class that is the same as the byte array class in AS?
I'm not sure why you would want to use Javascript here. Anyway, the string you pasted looks like the beginning of a JPG header. The problem is that a JPG will for sure contain NULs (characters with 0 as its value). This will most likely truncate the string (as it seems to be the case with the sample you posted). If you want to "stringify" the JPG, the standard approach is encoding it as Base 64.
If you want to persist data locally, however, there's a way to do it in Flash. It's simple, but it has some limitations.
You can use a local Shared Object for this. By default, there's a 100 Kb limit, which is rather inadequate for image files; you could ask the user to allot more space to your app, though. In any case, I'd try to store the image as JPG, not the raw pixels, since the difference in size is very significative.
Shared Objects will handle serialization / deserialization for you transparently. There are some caveats: not every object can really be serialized; for starters, it has to have a parameterless constructor; DisplayObjects such as Sprites, MovieClips, etc, won't work. It's possible to serialize a ByteArray, however, so you could save your JPGs locally (if the user allows for the extra space). You should use AMF3 as the encoding scheme (which is the default, I think); also, you should map the class you're serializing with registerClassAlias to preserve the type of serialized the object (otherwise it will be treated as an Object object). You only need to do it once in the app life cycle, but it must be done before any read / write to the Shared Object.
Something along the lines of:
registerClassAlias("flash.utils.ByteArray",ByteArray);
I'd use Shared Objects rather than Javascript. Just keep in mind that you'll most likely have to ask the user to give you more space for storing the images (which seems reasonable enough if you're allowing them to work offline), and that the user could delete the data at any time (just like he could delete their browser's cookies).
Edit
I realize I didn't really pay much attention the "we have chosen Gears to do so" part of your question.
In that case, you could give the base 64 approach a try to pass the data to JS. From the Actionscript side it's easy (grab one of the many available Base64 encoders/decoders out there), and I assume the Gear's API must have an encoder / decoder available already (or at least it shouldn't be hard to find one). At that point you'll probably have to turn that into a Blob and store it to disk (maybe using the BlobAPI, but I'm not sure as I don't have experience with Gears).
Related
I have been working with the WebcamJS library to stream video from the camera in the browser, but I have run into a major performance bottleneck. Since I am using Internet Explorer 11 (and cannot switch to a different browser), this library reverts to a Flash fallback for accessing the camera.
The ActionScript callback that returns the image is prohibitively slow, due to its many steps. When it returns the image, it first encodes its byte array as a PNG or JPG, and then to a base 64 string. This string is then passed using ExternalInterface to JavaScript, which decodes the image through a data URI. Given that all I need is the byte array in JavaScript, these extra steps seem wasteful.
I have had to tackle a similar problem before, in C++/Python. Rather than repeatedly pass the array data back and forth between the two languages, I used Python to pass a NumPy array reference at the start of the program. Then, they could both access the same data from then on without any extra communication.
Now that you understand my situation, here is the question: is it possible to pass a JavaScript Array or ArrayBuffer by reference to ActionScript? In that case, I could have ActionScript modify the JavaScript array directly, rather than waste time converting, encoding, and decoding the image for each frame.
(WebcamJS: https://github.com/jhuckaby/webcamjs)
Just for completeness, SharedObjects in flash store data, serialised with the AMF protocol, on the file system (in a very specific, sandboxed and locked place) where Javascript has no way to access to read the data.
Have you tried to simply call the ExternalInterface method and pass an array of bytes as an argument? it would be passed by value, automatically converted from the Actionscript data structure to the Javascript one, but you'd skip all the encoding steps and it should be fast enough ...
I am attempting to construct a loadTest in SoapUI wherein a file is selected at random from a pre-determined location on disk and inserted into a SOAP request parameter Base64 encoded; that request is then processed repeatedly according to the parameters of the loadTest. All the files are uniformly named, save for a numeric identifier I can obtain using a random() function.
So far I've set my file location and a random number generator to pull the appropriate files. I'm lukewarm on the concept of message Properties and contexts, but I'm struggling to pull together a coherent strategy for running this kind of test.
Does anyone have any experience with this kind of approach and if so, can any guidance be provided?
I am opting for JavaScript since it is a language I feel more comfortable in, but the documentation around JS in SoapUI specifically as it pertains to loadTesting is a little scattershot, so I'm also looking for help on how to fill gaps in documentation I've been able to chase down.
Thanks!
OK, on my commerce platform, shopping cart data is stored as a serialized array in the session. An issue popped up today where one of the item's size options had special characters for 1/4 and 1/2 sizes, eg; 7¼, 7½ etc., However when viewing the order that a customer placed for this item, the size value showed up like so: 7½
Troublshooting 101, I took to the site and placed the exact same order the customer placed... oddly, everything worked as expected and the issue did not replicate. Then I noticed that the order was placed via a "phone order" which is a back-end script that allows the store staff to compile a new order and charge / finalize it all on one screen. The system does this via use of jquery and ajax stuff to keep everything on-screen without having to have multiple "checkout pages".
Anyway, placed the same order over the phone order script and the problem reproduced just fine. Taking a deeper look into things, I noticed that on the "site" side where customers place orders, the cart data is serialized using the PHP function, then base64_encoded and stored "COMPRESSED" as such in the database with the order.
On the phone order side, the serialization is done via a php.js serialize function that is suppose to emulate the php serialize function identically. The serialized data is then POSTED to a handler along with the customers information etc. The CC is charged and the order is saved to the database just like on the site side.
Looking into it further, I compared the two "serialized" strings from both sides for the same exact order and there is a difference. On php's side, the value 7½ is shown as "s:2:7½", the Javascript version is shown as "s:3:7½"...
I've verified that my site's character encoding is Western (iso-8859-1) on all pages involved in this process.
I was able to work around the issue... once the "bad" serialized object is passed to php to save the order, then I unserialize it, then pass the resulting array/object off to a recursive function that runs a converter function(char2html) on every value, it converts any special character to its entity name code, essentially ½ becomes ½ and  becomes Â. I then use str_replace to get rid of any "Â" strings, then run it through another one of my functions(html2char) which coverts any &entityNames; back to their actual chcaracter.
Once that function is finshed running the object/array is then re-serialized using php's serialize function and everything works perfectly, no more Acric chars showing up on the orders placed on the phone order script.
So specifically I'm looking to figure out if there is some way I can force convert the UTF8 version of the ½ character in javascript to the 1 byte version (rather than the two byte UTF8 version that javascript is seeing), before I pass it to the serialize function in hopes that the serialize function will return the correct string, absent UTF8 characters.
That also being said there is some UTF8ness going on in the php.js serialize function but I'm not advanced enough in my JS coding to figure out if there is something INSIDE the serialize function doing this... or how to change it if there is.
Function reference:
http://phpjs.org/functions/serialize:508
Thoughts?
Let's say I'm making an HTML5 game using JavaScript and the <canvas> The varaibles are stored in the DOM such as level, exp, current_map, and the like.
Obviously, they can be edited client-side using Firebug. What would I have to do to maximize security, so it would be really hard to edit (and cheat)?
Don't store the variables in the DOM if you wish a reasonable level of security. JavaScript, even if obfuscated, can easily be reverse engineered. That defeats any local encryption mechanisms.
Store key variables server-side and use https to maximize security. Even so, the client code (JavaScript) is quite vulnerable to hacking.
You can use Object.freeze or a polyfill or a framework which does the hiding for you.
Check out http://netjs.codeplex.com/
You could also optionally implement some type of signing system but nothing is really impenetrable. For instance objects locked with Object.freeze or Object.watch can still be manually modified in memory.
What are you really trying to accomplish in the end?
What you could do is send a representation of the matrix of the game or the game itself or a special hash or a combination of both and tally the score at the server... causing the user to not only have to modify the score but to correctly modify the state of the game.
Server-side game logic
You need to keep the sensitive data on the server and a local copy on the browser for display purposes only. Then for every action that changes these values the server should be the one responsible for verifying them. For example if the player needs to solve a puzzle you should never verify the solution client side, but take for example the hash value of the ordered pieces represented as a string and send it to the server to verify that the hash value is correct. Then increase the xp/level of the player and send the information back to the client.
Anything that is living in the client can be modified. That is because in MMORPG the character's data is living on the server, so players can't hack their characters using any memory tools, hex editor, etc (they actually "can", but because the server keep the correct version of the character's data is useless).
A good example was Diablo 2: you have actually two different characters: one for single player (and Network playing with other players where one was the server), and one for Battle.net. In the first case, people could "hack" the character's level and points just editing the memory on the fly or the character file with an hex editor. But that wasn't possible with the character you was using on Battle.net.
Another simple example could be a quiz where you have a limited time to answer. If you handle everything on client side, players could hack it and modify the elapsed time and always get the best score: so you need to store the timestamp on the server as well, and use that value as comparison when you get the answer.
To sum up, it doesn't matter if it's JavaScript, C++ or Assembly: the rule is always "Don't rely on client". If you need security for you game data, you have to use something where the clients have no access: the server.
I'm able to record sound with a Flash application embedded in my website, this audio is saved to a ByteArray, which I need to pass to Javascript in order to post to my server along with other required data.
I know I can use AS3 ExternalInterface class to communicate with Flash from Javascript, but what would be the appropriate format or variable type in javascript to hold the ByteArray, and how can I ensure that I won't lose much audio data when doing so?
This code worked for me (rec is ByteArray):
rec.position = 0;
rec.compress();
var b64:Base64Encoder = new Base64Encoder();
b64.encodeBytes(rec);
ExternalInterface.call('soundRecorded', b64.toString());
It sucessfully handles about 6 megabytes of data (I didn't try more).
Maybe it's not possible for you for some reason I'm not aware of, but if that's not the case, I'd post the data directly from Actionscript (you can send binary data).
Anyway, if you have to relay the data to JS, the safest way would be base64-encoding the ByteArray. After that you have a string that will not have any control (read: problematic) characters.
Size is of course something to take into account. I don't know what are the limitations of ExternalInterface (I've only ever used it to pass small ammounts of data), but you'll most likely hit a hard limit there. LocalConnection objects have a limit of 100 kb or so if I recall correctly (these are not related to the ExternalInterface api -at least not directly- but I mention it just as a remainder of the possible limitations). If you're working with raw audio, your data will be rather big, so you'd have to figure out how to compress it (and decompress it in the JS end or in the server) and also, probably, how to send it in chunks, as sending it all at once will likely be impossible if the data is too big.
Again, if possible, I'd post directly from Actionscript and would use at least the ByteArray's compress method before sending the data.