Remote shared object not firing onSync method after update - actionscript-3

I have game server, FMS 4.5 on Windows, already working prefect, and client apps were created in old CS4, and all is perfect.
Now I want to create a mobile app in AS3, and have a problem with remote shared object, which is working perfect in old flash program.
When users are logged into app, I'm receiving an update with onSync method. But whenever remote shared object is updated, I'm not receiving updates.
for example, on client, where I have main_nc as netConnection object:
var ncu_so:SharedObject = SharedObject.getRemote("Zusers", main_nc.uri, false);
ncu_so.addEventListener(SyncEvent.SYNC, syncNCU);
ncu_so.client=this;
ncu_so.connect(main_nc);
private function syncNCU(e:SyncEvent):void {
........
//here I receive new info....
}
and sample on server...
application.onAppStart = function(){
this.Zusers_so = SharedObject.get( "Zusers", false );
...........
}
function sampleUserEnter(client) {
var t=new Object();
t.username=client.username;
application.Zusers_so.setProperty(client.id,t);
//this one call is synced with app
}
function sampleChangeName(client,newName) {
var t=application.Zusers_so.getProperty(client.id);
t.username=newName;
application.Zusers_so.setProperty(client.id,t);
//this IS NOT syncing with app
}
As I said, this code is working with old flash software, but wont update when using AS3. Any idea?

I found an easy solution. Not sure why it works but it works....
var ncu_so:SharedObject = SharedObject.getRemote("Zusers", main_nc.uri, false);
ncu_so.addEventListener(SyncEvent.SYNC, syncNCU);
//I add the listener for checking status
ncu_so.addEventListener(NetStatusEvent.NET_STATUS, statusNCU);
ncu_so.client=this;
ncu_so.connect(main_nc);
private function syncNCU(e:SyncEvent):void {
........
//here I receive new info....
}
//In function for NetStatus event, I just set a simple property
//which I do not use in the app..
//and sunchronization start working as usual after initial sync
private function statusNCU(ev:NetStatusEvent):void {
if (ev.info.code == "NetConnection.Connect.Success") {
ncu_so.setProperty("anyPropertyName",new Date());
}
}

Related

How to simulate Geolocation service AS3

I'm creating an app that is using Geolocation servioce on phone o send location/time data over the internet. And that is working just fine. Problem is that I cannot test it in Flashdevelop, cause Geolocation is not supported, so I have to upload every time new code and test it on phone. Is there any way to simulate Geolocation service in Flashdevelop? Or generally, on desktop PC?
Sorry for bothering ... I found out... quite simple answer was..
private function startLocating():void {
var myLat:Number=44.2343;
var myLong:Number=20.9432;
_geo = new Geolocation();
_geo.addEventListener(GeolocationEvent.UPDATE, Handler1 );
if (Geolocation.isSupported) {
if (!_geo.muted) {
_geo.setRequestedUpdateInterval(1000);
} else {
trace ("Location service not turned on.");
}
} else {
/* this code is working when Geolocation is not supported */
_geo.dispatchEvent(new GeolocationEvent(GeolocationEvent.UPDATE,false,false,myLat,myLong));
}
}
private function Handler1(ev:GeolocationEvent):void {
var latitude:Number = ev.latitude;
var longitude:Number = ev.longitude;
.....
}

How can i get AS3 facebook API to init on a self signed https site

I am setting up a facebook app - with the AS3 facebook API. The first thing i do is call Facebook.init(). When this is done on our normal development setup (a normal http site) - this works perfectly and i am able to access the graph. However when i switch to a https site (with a self signed certificate) Facebook.init() never fires the callback. I have crossdomain.xml set up correctly to allow all and security false.
Anybody know how i could set this up so that it will work.
Indeed the Facebook connection with the FB API AS3 doesn't work anymore since august...
With the FlashWebExemple.fla from http://code.google.com/p/facebook-actionscript-api/downloads/detail?name=GraphAPI_Examples_1_8_1.zip
Facebook.init(APP_ID, onInit);
protected function onInit(result:Object, fail:Object):void {
trace("on INIT");
if (result) { //already logged in because of existing session
outputTxt.text = "onInit, Logged In\n";
loginToggleBtn.label = "Log Out";
} else {
outputTxt.text = "onInit, Not Logged In\n";
}
}
No "on INIT" message...
Anyone ?
Get accessToken from FB.init in JS
Pass accessToken to Flash (swf params or ExternalInterface)
Call Facebook.init() with accessToken and set options.status = true
var options:Object = {};
var accessToken:String = null;
if(!StringValidator._isNullOrEmpty(m_swfParameters._accessToken))
{
options.status = true;
accessToken = m_swfParameters._accessToken;
}
Facebook.init(m_facebookProvider._appId, _onInitedCallback, options, accessToken);
if(options.status === true)
{
_onInitedCallback(options, null);
}

Flash AS3 Call a WSDL in a for loop

I'm using the Flex SOAP web service, connecting to our WSDL and everything is dandy. However, I'm new to web services and the web guy is on holiday, so I'm a bit confused. The first thing I'm doing is running a check connection:
private function configXMLHandler(event:LoaderEvent):void {
fws.wsdl = checkWSDL;
fws.loadWSDL();
fws.addEventListener(LoadEvent.LOAD, wsdlLoaded);
}
private function wsdlLoaded(event:LoadEvent):void {
checkAbstract = fws.getOperation("retrieveAssetIdbyLabel");
checkAbstract.arguments = ["poll-asset-do-not-remove"];
var token:AsyncToken = checkAbstract.send();
token.addResponder(new Responder(checkAbstractResult, checkAbstractError));
}
private function checkAbstractError(event:FaultEvent):void {
trace('Error in the WSDL');
}
private function checkAbstractResult(event:ResultEvent):void {
if (event.result.returnCode == 0) {
trace('Web service check ok');
initContentLoader();
} else {
trace('Error in the WSDL');
)
}
}
This works fine, I get the result I expect, and so I move on. I then need to iterate through an XML list and call the same web service function for each asset in that XML, my thinking was to use a loop:
private function initContent(event:LoaderEvent):void {
assetList = event.target.content.asset;
for (var i:int = 0; i < assetList.length(); i++) {
assetAbstract = fws.getOperation("retrieveAssetIdbyLabel");
assetAbstract.arguments = [assetList[i + assetCount].assetLabel]; //get the current index in the xmllist + the assetCount, grab the corresponding assetLabel from the XML and pass that to the web service
trace(assetAbstract.arguments);
var assetToken:AsyncToken = assetAbstract.send();
assetToken.addResponder(new Responder(getAssetResult, getAssetError));
}
}
private function getAssetResult(event:ResultEvent):void {
var treasuresAsset:TreasuresAsset = new TreasuresAsset(event.result.returnCode, assetList[assetCount].asset.assetLabel, assetList[assetCount].asset.assetImage, assetList[assetCount].asset.assetDescription);
addChild(treasuresAsset);
assetCount++; //increase the asset count
}
private function getAssetError(event:FaultEvent):void {
trace(event.fault);
trace('An error occured when we tried to get an asset id in the loop');
}
I now get an error:
Error opening URL 'http://www.nhm.ac.uk/web-services/VisitorService/'
SOAPFault (Server): org.apache.axis2.databinding.ADBException: Unexpected subelement RetrieveAssetIdbyLabel
My immediate thought was that I need to create a new instance of the web service for each asset in the xml, and repeat my first code over and over. Can I use the web service only once, do you need to recreate the entire procedure?
Thanks.
OK, so I figured this out, and it was a simple XML namespace issue.
I replaced:
assetAbstract.arguments = [assetList[i + assetCount].assetLabel];
With:
var sender:String = assetList[i + assetCount].assetLabel;
assetAbstract.arguments = [sender];
And all is working.

Adobe Air and Dropbox

I'm trying to integrate dropbox into my BB Playbook app using adobe air in flashbuilder 4.6. I got the API from http://code.google.com/p/dropbox-as3/wiki/EXAMPLES and I'm also using that example.
public function getRequestToken():void
{
dropAPI.requestToken();
var handler:Function = function (evt:DropboxEvent):void
{
dropAPI.removeEventListener(DropboxEvent.REQUEST_TOKEN_RESULT, handler);
var obj:Object = evt.resultObject;
reqTokenKeyLabel.text = obj.key;
reqTokenSecretLabel.text = obj.secret;
// goto authorization web page to authorize, after that, call get access token
if (oauthRadioBtn.selected) {
Alert.show(dropAPI.authorizationUrl);
}
};
dropAPI.addEventListener(DropboxEvent.REQUEST_TOKEN_RESULT, handler);
if (!dropAPI.hasEventListener(DropboxEvent.REQUEST_TOKEN_FAULT)) {
dropAPI.addEventListener(DropboxEvent.REQUEST_TOKEN_FAULT, faultHandler);
}
}
This executes as expected but I don't know how to go further, I tried sending the user to the link generated and I allow the application but the get access token still fails. I feel like there is missing code, how does my application know what the access token is? should I not be getting something back from dropbox when the user allows the application?
Once the user has accepted the app in the web browser you should call this function in order to get the access token and secret:
public function getAccessToken():void{
dropAPI.accessToken();
var handler:Function = function (evt:DropboxEvent):void{
dropAPI.removeEventListener(DropboxEvent.ACCESS_TOKEN_RESULT, handler);
var obj:Object = evt.resultObject;
myAccessToken = obj.key;
myAccessSecret = obj.secret;
};
dropAPI.addEventListener(DropboxEvent.ACCESS_TOKEN_RESULT, handler);
if (!dropAPI.hasEventListener(DropboxEvent.ACCESS_TOKEN_FAULT)) {
dropAPI.addEventListener(DropboxEvent.ACCESS_TOKEN_FAULT, faultHandler);
}
}
Once you have them you can save them for future use. After that you have establish connection with Dropbox.
I hope this will help you

getting a shared object to expire after browser session in FLASH?

I'm looking for a way to play flash animated content once ( even as the user navigates to different HTML pages with similar flash content) and expire after a set amount of time or after the browser is closed.
I'm aware I could use a shared object for this but can't seem to find info about how to clear them at browser session end.
I am open to using javascript or PHP to assist .
your help is appreciated -
thanks -MW
Instead of using a SharedObject, you could create two simple server-side services: one that maintains the session, and one that exposes the session through a generated XML file that your flash application could use.
The first service would set some session variables and should be called whenever the video is played. It could look like this:
<?php
// start-video.php
session_start();
$_SESSION['hasWatchedVideo'] = true;
$_SESSION['watchedVideoAt'] = time();
?>
The second service is the one that generates the XML response based on the session. It might look like this:
<?php
// flash-config.php
session_start();
// set expiration to 5 min
define(VIDEO_TIMEOUT, 300);
$playVideo = "true";
if($_SESSION['hasWatchedVideo']
&& (time() - $_SESSION['watchedVideoAt']) < VIDEO_TIMEOUT) {
$playVideo = "false";
}
header("Content-Type: text/xml");
echo "<config><playVideo>{$playVideo}</playVideo></config>";
?>
Then from your Flash application, you could do this:
/**
* Called whenever the app is loaded.
*/
protected function init():void {
var u:URLLoader = new URLLoader();
u.addEventListener(Event.COMPLETE, onComplete);
u.load(new URLRequest("http://example.com/flash-config.php"));
}
/**
* Determines whether or not the video should play based on the
* config service response.
*/
protected function onComplete(e:Event):void {
var x:XML = new XML(e.target.data);
if(x.playVideo == 'true') {
playVideo();
}
}
/**
* Should be called either when the video starts playing. I just tied
* it to a user click here.
*/
protected function playVideo():void {
// call the service to update the session
var u:URLLoader = new URLLoader();
u.load(new URLRequest("http://example.com/start-video.php"));
// ... play video code ...
}
I think this approach gives you a bit more flexibility than using a SharedObject. Hope that helps.
UPDATE:
You could use a session cookie in the browser as well. Basically set the expiry date to '0' and the cookie will expire when the user closes the browser. (Note: when I tested this in Firefox, closing the tab was not enough to kill the cookie. The entire browser had to be closed.)
You can use ExternalInterface, or a utility library like this. Using the library, you could have code like this in your flash application:
function playVideo():void {
if(!CookieUtil.getCookie('playvideo')) {
CookieUtil.setCookie('playvideo', 'true', 0);
// ... play video code ...
}
}
Whenever the user closes the browser, the cookie will be cleared. Next time they visit your site, the video will play again. Not sure if this is more inline with what you're look for, but hope it helps.
I modified your code a tad so it will be killed on sesion end ...
the PHP ...
<?php
// flash_php_session_cookie.php
$cookie= "false";
if (isset($_COOKIE["cookie"]))
$cookie= "true";
else
setcookie("cookie", "true", 0);
echo "<config><cookie>{$cookie}</cookie></config>";
?>
the FLASH ...
// the folowing functions handle call coresponding PHP files to handle cookies ...
// re-configure these to the location of the swf ...
var flashConfigURL:String ="flash_php_session_cookie.php";
//Called whenever the app is loaded ...
function initCookieFunc():void {
var u:URLLoader = new URLLoader();
u.addEventListener(Event.COMPLETE, onComplete);
u.load(new URLRequest(flashConfigURL));
}
// Determines whether or not the cookie exists / (assumes theres a text field named T on the stage) ...
function onComplete(e:Event):void {
var x:XML = new XML(e.target.data);
if (x.cookie == 'false') {
T.appendText("cookie doesn't exist yet");
} else {
// cookie exists ...
T.appendText("cookie exists");
}
}
initCookieFunc();
I am going to keep a loose version of the "TIMEOUT"
version as well.
It's great to have an answer to this
Thanks again RJ for the invaluable code
-MW
You'll just have to expire the SharedObject yourself. It's not complicated.
This way your .swf will be completely self contained, not relying on anything external which IMO is a good thing.
package {
import flash.display.Sprite;
import flash.net.SharedObject;
import flash.net.SharedObjectFlushStatus;
public class SharedObjectExample extends Sprite {
private var _so:SharedObject;
private var _now:Date;
private var _last_played:Number;
private static const EXPIRE_TIME:Number = 1000 * 60 * 60 * 24; // 24hrs in msec
public function SharedObjectExample() {
// create a new date for the current time to compare against
_now = new Date;
// create a new shared object
_so = SharedObject.getLocal("application-name", "/");
// try read from the shared object
if (_so.data.last_played) _last_played = _now;
// if no value is set we play the video and set the current time
if (!_last_played) {
// play video here
_last_played = _now.time;
// check if the "cookie" has expired and it's time to play again
} else if ( _now.time - _last_played > EXPIRE_TIME) {
// play video here
_last_played = _now.time;
} else {
// do nothing
}
// and finally, save
saveValue();
}
private function saveValue(event:MouseEvent):void {
// i've removed the code that asks the user for permission if the request for storage is denied
_so.data.last_played = _last_played;
var flushStatus:String = null;
try {
flushStatus = _so.flush(1000);
} catch (error:Error) {
trace("Could not write SharedObject to disk");
}
}
}
}