How to use Remote Shared Objects - actionscript-3

I'm trying to use a remote shared object to send data messages between the client and server using the sharedobject.send method for a chat application.
I am really having difficulty understanding the documentations. The code i attempted to use simply didn't work.
Can someone be kind enough to show me the relevant API calls? And, take a close inspection at my code and tell me were exactly i am going wrong?
Thank You.
Client-Side
import flash.net.NetConnection;
import flash.events.NetStatusEvent;
import flash.events.SyncEvent;
var nc:NetConnection = new NetConnection();
nc.connect("rtmfp://fms/exampledomain");
nc.addEventListener(NetStatusEvent.NET_STATUS, netHandler);
function netHandler(event:NetStatusEvent):void {
if (event.info.code == "NetConnection.Connect.Success") {
trace("Your Connected");
//Creating the sharedobject
var my_so:SharedObject = SharedObject.getRemote("users", nc.uri, false);
my_so.connect(nc);
my_so.addEventListener(SyncEvent.SYNC, syncHandler);
my_so.setProperty("users");
my_so.setDirty("users");
function syncHandler(event:SyncEvent):void {
var changelist:Array = event.changeList;
}
my_so.send function sendMessage(str){
Server-Side
application.onConnect(clientObj)() {
application.acceptConnection(clientObj) {
trace("connected up");
}
var my_so = SharedObject.getRemote("users", false);
my_so.send("Hello user", "Its only a test");
}

After editing your question, it looks like some code is missing in your client-side sample.
From what I see, you don't need the client-side code for your example to work. You can call the send() method directly from the client. But to test whether it works or not, you will need to have two clients connected.
About your NetConnection or your SharedObject, make sure you add your event listeners before you call the connect() method.
If what you want to achieve is simply sharing data between clients, then you don't even need to use the send() method but simply set properties on your shared object. But be aware of the following:
my_so.setProperty("users");
is actually deleting the key users as it is the same as this:
my_so.setProperty("users", null);
Finally, you would need to call setDirty() in very specific cases, but not in this one. Have a look at this answer for a more detailed example on how to share data with SharedObjects

Related

How to create Synchronous Function Flex

I have created a swf project with flex and i have some checkboxes on it and whenever the checkbox seleced it will call the checkbox handler:
function checkBoxHandler() {
//call resultHandling
var obj:myObjectType = new myObjectType();
resultHandling(obj)
}
function resultHandling(myObject:myObjectType) {
//implementation code to send a request to server side
}
is it possible to make the "resultHandling(...)" to be a synchronized function? So there will be a que whenever we make a call to that function especially when there are multiple function calls
As Flex is Flash the limitations to Flash apply to Flex too. One of these is (Actually in newer Flash versions this no longer is 100% valid) that Flash has only one thread. This thread does everything from updating/drawing the ui, processing the application logic, handling IO, etc. Therefore a synchronous call would be a blocking call and in Client-Server communication this block can be quite long. Therefore Flash doesn't support blocking calls to a server and you won't be able to find a solution for this ... unfortunately.
But be assured, actually you will start creating more robust applications this way. I have noticed creating more and more asynchronous solutions even in places I could use synchronous calls :-)
you can create an arraycollection and store all your myObjectType objects in it. Then do something like-
var arr:ArrayCollection = new ArrayCollection();
function checkBoxHandler() {
//call resultHandling
var obj:myObjectType = new myObjectType();
arr.addItem(obj);
}
function resultHandling(myObject:myObjectType) {
//implementation code to send a request to server side
}
function webServiceResponseHandler(){
//receive the response from server
sendWSRequest();
}
function sendWSRequest(){
if(arr.length > 0)
{
resultHandling(arr.getItemAt(0));
arr.removeItemAt(0);
}
}
Most Flash I/O is asynchronous and there is no way to change that. Consider using inline nested handlers
function checkBoxHandler() {
var obj:myObjectType = new myObjectType();
var resultHandling:Function = function():void {
//you can just reference obj here
var resultHandling2:Function = function():void {
};
};
//implementation code to send a request to server side
}
or use a task scheduler such as the Parsley Command Framework.

AsyncToken behaviour with Socket- Flex

I am using FlashSocket on my client side to make calls to socket.io on node.js server.
But i want specific values and function references to be available in the socket event listeners.
One approach that came to my mind was to pass the required values along with the request and make the server to send those parameters back along with the data. But that doesn't seem to help since I need the function handlers to be returned as well with the result.
The way i am doing it with http request is:
var token:AsyncToken = _service.send(item.params);
token.id = _tokenId;
token.params = item.params;
token.handler = item.resultHandler; // this would be called later in result or fault event handlers.
Is there a way to achieve this in flex sockets?
Thanks in advance.
You could use AsyncResponder class and anonymous functions.
var token:AsyncToken = _service.send(item.params);
token.addResponder(new AsyncResponder(
function(event:Object, token:Object = null):void {
// result handler, it has access to item.params, etc.
},
function(error:FaultEvent, token:Object = null):void {
// fault handler, it has access to item.params, etc.
}
));

How to pass on data through navigateToURL?

navigateToURL(new URLRequest("other.html"), "_self");
other.html has a swf embedded in it.
Is there a way I can pass on variables to the swf embedded in other.html.
The reason is that I need to tell the swf if the user has logged in or not, and if he has logged in, pass it the user details. Feel free to suggest alternative methods that might me more efficient.
My entire website is made in flash.
Thanks
haven't written flash in a long time, but assuming that '+' is the string concatenation method...
for GET variables i would just do:
var url:String = "other.html";
url += "?someParam=someValue";
url += "&someOtherParam=someOtherValue";
navigateToURL(new URLRequest(url), "_self");
which is effectively making your url:
"other.html?someParam=someValue&someOtherParam=someOtherValue"
Edit:
something like this to actually grab the query vars...
function loaderComplete(myEvent:Event)
{
var myQueryStrings=this.loaderInfo.parameters;
var someParamValue:String=myQueryStrings.someParam;
}
this.loaderInfo.addEventListener(Event.COMPLETE, loaderComplete);

as3 calling a function in another class [duplicate]

UPDATE: OK I am about ready to give up on Pacakages and classes. No answers coming. Not sure what to do. I tried to make the question easier and made a new post but I was down voted for it. as3 calling a function in another class
I am TOTALLY NEW to using PACKAGES and CLASSES. I am finally converting over from the timeline after having so many issues. Please be patient with my lack of knowledge. I need to know how to call a function in the child swf file I loaded from code in the maintime in the parent swf.
There are 2 swf files. Main.swf and pConent.swf
1. Main.swf has code in the timeline of the first frame.
2. pConent.swf is loading a PACKAGE CLASS as file.
QUESTIONS
I am trying to call a function in it from its parent Main.swf. How do I do this?
Here is sections of the code from both. Thanks
Main.swf CODE /// is an AIR for Andrid swf
function LoadContent()
{
TheContent.load(new URLRequest( "pContent.swf"));
TheContent.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadContentTWO);
function LoadContentTWO(e:Event)
{
Content = TheContent.content as MovieClip;
pContent = Content as Object;
addChild(TheContent);
var OSS:String = "device";
trace(pContent); //// comes out as: [object pContent]
pContent.GetOnlineStatus(OSS); ///// HOW DO I GET THIS TO CALL FUNCTION
}
}
A SECTION OF THE "CLASS" in pContent.swf I am trying to call
public function GetOnlineStatus(OS:String)
{
if(OS=="online")
trace("inside ONLINE" );
}
if(OS=="device")
{
trace("inside DEVICE" );
}
}
THE ERROR I AM GETTING
TypeError: Error #1006: GetOnlineStatus is not a function.
UPDATE: I decided to post the FULL PACKAGE ( my first) to see if I am doing it right.
package
{
import flash.display.MovieClip;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.display.*;
import flash.media.Sound;
import flash.system.*;
import flash.media.SoundChannel;
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class pContent extends MovieClip
{
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
var ScreenY = flash.system.Capabilities.screenResolutionY;
var ScreenX = flash.system.Capabilities.screenResolutionX;
var swf:String;
var daSounds:String;
var images:String;
var videos:String;
var OnlineStatus:Boolean;
//++++++++++++++++++++++++
//++++++++++++++++++++++++
public function pContent()
{
BG.addEventListener(MouseEvent.CLICK, mouseHandlerdown);
}
//++++++++++++++++++++++++
//++++++++++++++++++++++++
//-------- * FUNCTIONS * --------
//-------------------------------
public function mouseHandlerdown(event:MouseEvent):void
{
alpha = .3; // testing
}
public function GetOnlineStatus(OS:String)
{
if(OS=="online")
{
OnlineStatus = true;
Security.allowDomain("*");
trace("inside THE PATH " + ThePath.text);
daSounds = "http://mycontactcorner.com/upload/files/";
swf = "http://mycontactcorner.com/upload/files/";
trace("inside THE DEVICE ONLINE" );
OnlineStatus = false;
swf = "";
daSounds = "content/sounds/";
//LoadMenu();
LoadStage();
LoadBeau();
}
if(OS=="device")
{
trace("inside THE DEVICE ONLINE" );
}
}
//------ * END FUNCTIONS * -----
//------------------------------
}// END FUNCTION pContent
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}//// END PACKAGE
Don't be disappointed, but I won't have a "real" answer to your question, and I am really not going to work through all of your code to solve it, either. It is your own task to learn how to do this, and unless people here are very, very hungry for reputation, no one will do it for you - we will only help you to find the right way.
Your problem is not "packages and classes", so please do not give up on them. They will help you a great deal, once you've started to understand them. Your problem is, that you are not facing a single problem, but actually at least two (and quite substantial ones, I might add):
You need to go back to learn about the basics of object oriented programming in ActionScript. You won't have much luck getting answers to questions like this, otherwise. And believe me, I don't mean that in a patronizing way - it is simply a complicated matter, and it is hard to communicate complicated issues, both when you don't know the terms to express them, or when your counterpart doesn't understand them. Think of it like a high school math problem: You won't ever find a solution to your trigonometry question (or get a decent answer), unless you learn some basic algebra first.
You also have a problem related to loading, application domains, and the Flash Player security model - which are all far more complicated than what you should aim at when trying out OOP stuff. This can be a major obstacle, and unless you want to frustrate yourself, you should try to avoid it, until your program actually runs.
So this here is my advice: Always try to solve one problem at a time. Do not work yourself into such complex scenarios as the one you are in right now, but take step by step, until you've reached a level where you are confident with what you are doing.
Your first issue should be to understand what's going on with classes and objects. Everything else will come later. You should try to isolate your problem in the pContent.swf and get that to work first - or better yet, put everything you need for your program into a single file. Convert to using classes. Then, once you know how to work with those, start learning about more advanced OO, decoupling your code using interfaces, type casting and loading binaries at runtime.
//makes contact with classs but comes out as: [object pContent]
its because you said
pContent = Content as Object;
I am not sure why you are doing this extra step
Change it to this
Content = TheContent.content as MovieClip;
// pContent = Content as Object; //NO NEED OF THIS
addChild(Content); // just in case this gives error change it as addChild(Content as Object);
var OSS:String = "device";
trace(Content); //now see the difference
Content.GetOnlineStatus(OSS); // it calls now
Also, give the link where you posted that scary question :P if it has rest of the code
Sorry if this does not sound like an answer, but I'm going to write a couple of doubts that I have reading your code that can possibly lead to the solution:
Why are you casting it to MovieClip? If you cast it as MovieClip, the compiler it is going to tell you that the method "GetOnlineStatus" doesn't exist, because MovieClip class doesn't have it! I think you have to cast it as pContent
Why are you trying to casting TheContent.content? What is "content"? I had a look to your previous post and I cannot see anything called "content"?
If I ignore my second doubt (TheContent.content issue), I would change the code like this:
Content = TheContent.content as pContent; // your class it's called pContent
addChild(Content);
Content.GetOnlineStatus(OSS); // it calls now
Also, keep in mind that generally it's a good pratice to capitalize name of classes and not variables.
Let me know!
private function GetOnlineStatus
Try making this a public function instead. When it's private it can't be accessed outside the scope of the class that owns it.
I believe that in order to make this work, content property of the Loader. You have to create a reference to the loaded SWF as the class you are trying to call. This class has to be included in the main SWF's project. Then you can call the functions of that particular class in the child.
function LoadContent()
{
TheContent.load(new URLRequest( "pContent.swf"));
TheContent.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadContentTWO);
}
function LoadContentTWO(e:Event)
{
var pContent:GetOnlineStatus = GetOnlineStatus(e.target.content);
addChild(e.target.content); //Assuming that "TheContent was
// declared as var TheContent:Loader , you'd be adding the loader to the stage when I think you actually wanted // to add the content.
var OSS:String = "device";
trace(pContent); //// comes out as: [object pContent]
pContent.GetOnlineStatus(OSS); ///// HOW DO I GET THIS TO CALL FUNCTION
// This should work now. If not, try to loading a function that is not the class' main function. Because I think you might get an "unable to call static function error". I'm a begginner too though, so sorry if I'm wrong. Example: pContent.GetOnlineStatusFunction(OSS);
}
This answer assumes that the pContent.swf contains a class file that looks like this:
package {
public class GetOnlineStatus {
public function GetOnlineStatus (OSS:String) {
//Do your GetOnlineStatus Logic. This is the main function.
}
/*public function GetOnlineStatusFunction (OSS:String) {
//Example non-main function
} */
}
}
Source: http://www.scottgmorgan.com/accessing-document-class-of-externally-loaded-swf-with-as3/

Reading in a File (AS3) and repeatedly/dyamically accessing the data

This may be a tired old question, but I have yet to find a good answer. Say for instance you have a class that reads in an xml file to get information such as a grocery store items, prices, etc. This class also allows you to retrieve the information about a grocery store item with a get() function.
var grocery:GroceryStore = new GroceryStore(); //create a class that
//reads in xml about
//grocery items
grocery.get("lettuce"); //get some data
In this scenario, I am constantly running into issues because the get() function is being called before the event that loads in the xml file. It wouldn't make sense to place the get() in the onLoad event for the xml file because I want it to be re-usable and dynamic. Also, AS3 doesn't have a wait() function so I can't stall until the file is loaded? Does anyone have an idea on how to read in a file and then be able to safely access the data dynamically and repeatedly? Hopefully this example and my question is thorough enough, if not let me know.
Thanks
You can use events - listen for the complete event to be dispatched.
Add the following code to GroceryStore class
//constructor or a load method
var ldr:URLLoader = new URLLoader();
ldr.addEventListener(Event.COMPLETE, onLoad);
ldr.load(new URLRequest(xmlurl));
function onLoad(e:Event):void
{
//process xml here
dispatchEvent(e);
}
Now use it as:
var grocery:GroceryStore = new GroceryStore();
grocery.addEventListener(Event.COMPLETE, onGroceryLoad);
function onGroceryLoad(e:Event):void
{
grocery.get("lettuce");
}