Getting information from a shared object on the adobe media server - adobe

I am currently stuck and cant find any answers anywhere!! So any help at all would be great!
Currently Im trying to create a sharedObject on a client and send a string from the client containing information based on phone hardware(e.g. accelerometer and geolocation) to ams. From here I want to be able to access information from the sharedObject on the server in the main.asc to use elsewhere!
This is where the problem is occurring I cant access the shared object sent by the client. I sent my shared object like this:
//It's a best practice to always check for a successful NetConnection
protected function onNetStatus(event:NetStatusEvent):void
{
switch(event.info.code)//Check for a successful NetConnection
{
case "NetConnection.Connect.Success"://If the netConnection is a success#
so = SharedObject.getRemote("Data", nc.uri, false);//
so.connect(nc);//connect the sharedObject to the srever
so.addEventListener(SyncEvent.SYNC, syncHandler);//The sync listener
publishCamera(); //Publish the video
case "NetStream.Publish.Start"://If the netStream is a success
//etc
}
}
//It's a best practice to always check for a successful NetConnection
protected function syncHandler(event:SyncEvent):void
{
so.setProperty("username", nameForData);
so.setProperty("age", 21);
so.setProperty("nationality", "irish");
trace("Local"+so.data.username);
Im just not sure how to access so from server side!! I know this works as I have tested it but if there are better ways to implement it I would be glad to get advice!Below is proof that it is hitting the server
Update
Still stuck so I am adding a bounty and updating where I am and how I have progressed!
I have the information hitting the server(sometimes its not constant I dont know why)
Example is sometimes I get this in the admin console most times i have no information in the properties tab
What I am trying to do is to get the file to save every time I flush() the shared object so I can use it elsewhere
My server code is straight from the adobe api this is how it looks in the main asc:
in my onAppStart() I added these lines at the end:
application.allowDebug = true;
application.clearOnAppStop = false;
var Shared = SharedObject.get("Data", true);
trace("Name: "+Shared.name);
trace("Username: "+Shared.getProperty("username"));
in my onAppStop() I added these lines at the end:
var Shared = SharedObject.get("Data", true);
Shared.clear();

The serverside code for shared objects is (almost) the same as the client side.
So using so.getProperty(propertyName) should do the job.
If not check the server side shared object reference from adobe. Maybe that helps.
Hope i didn't missunderstand your question.

Related

What I misunderstood about the Mediator Pattern?

I'm new here and a beginner architect. I'm helping the company I work to design our new product and since I start it, I read a lot about but is never enough.
I decided to use Mediator Pattern (with Mediatr) to call my application layer.
It's cool and I got how to work with it sometimes, but sometimes I get confused.
For example, when we publish a document on our new product, we uses a RequestHandler to do everything and check all rules it needs, it's fine and works like a charm, but, when I want just a quick data, it looks likes too much for just a simple thing.
As an example, every time the user do any kind of action on my web application, I have to check if he is still logged. We have single login per user, so, if the same user connect anywhere else, the older session expires. We do it by saving on database.
On every action of my app, I go to base and check if the session key is the same, as bellow.
var sessionKey = bibliotecaCookie.Value;
var mediator = controller.GetMediator();
var isUserSessionKeyValidRequest = new IsUserSessionKeyValidRequest()
{
sessionKey = sessionKey
};
var isValidSession = mediator.Send(isUserSessionKeyValidRequest).Result;
if (!isValidSession)
throw new UnauthorizedAccessException();
So, I have a RequestHandler (a Handler and a Request which returns a bool) just to check if the user session is ok.
When the handler catches this request, it goes to database and execute a simple rule which is "Is the passed session the same as the stored session key?".
Is it right? Is it the right approach? Did I understand it right?
Thanks in advance guys

Technology to send "real-time" console output to the client's browser

I have a .NET console application that I want to start on the server of an ASP.NET MVC application. It produces output continuously for a certain time and I want to intercept this output and show it to the client in his browser window.
From another console application, I can do it like this:
public static void Main(string[] args)
{
Process process = new Process();
process.StartInfo.FileName = "RandomOutputCreator.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, e) =>
{
Console.WriteLine(e.Data);
};
process.Start();
process.BeginOutputReadLine();
Console.ReadKey();
}
The problem is that in the MVC application, I can't push the data I read to the client, but rather rely on requests to the controller to get my data.
Something like WebSockets could maybe help me here, but I'm new to this kind of thing and wonder if there might be a "built-in" way to accomplish this.
Then there's the Web API thing. Could this be of use perhaps, since it seems to go well with MVC?
(Since I do not know what a fitting technology might be, please excuse the lack of tags and feel free to fill some in that you think fit).
This topic typically reminds me of a tutorial I followed in order to allow real-time communication from my browser to an ASP.NET application.
In summary : What you're looking for are indeed WebSocket, and there is no standard built-in functions to handle that. But, in order to help you doing some stuff, you still have the library signalR!
Here's the link to the referenced tutorial : http://www.asp.net/signalr/overview/getting-started/real-time-web-applications-with-signalr
You can try "print" console output in a separate frame (see iframe HTML tag).
You should set one of your actions as a source (URL) of the frame. You'll need to configure the IIS to run this action without execution time limit.
Next, your action should run an external program, intercept its output, and write it to HTTP output (see ContentResult).
I have a small project that does exactly that: https://github.com/vtortola/WebSocketListener/wiki/WebSocketListener-Terminal-Server
Give it a look, it may give you some ideas.

Meteor.JS: Subscribe no working

Im trying to subscribe my client side to my userFriends collection and Chrome's console display: userFriends is not defined
This is my code:
Server side...
userFriends = new Mongo.Collection("friends");
console.log(userFriends.find().fetch())
Meteor.publish("friends", function () {
return userFriends.find();
});
NOTE: The console.log display in the terminal an empty array which is good
Client side...
Meteor.subscribe("friends");
console.log(userFriends.find().fetch())
NOTE: This is where Chrome's console display the error
what am I doing wrong ?
Thank you
UPDATE 1: Now I can see the Friends collection in Chrome's console, but i cant insert data. I have the subscribe in client.js inside my client folder and my insert code is in friend.js inside client folder aswell.
The collection needs to be defined on both the client and the server. Typically this is done by placing the definition in a shared directory like lib:
lib/collections/user-friends.js
userFriends = new Mongo.Collection('friends');
Note the convention is to name the collection with the capitalized camel case version of the collection name. So calling it Friends would be more typical.
You need to declare the collection on both environments using shared code.
lib/user-friends.js
userFriends = new Mongo.Collection("friends");
client/user-friends.js
Meteor.subscribe("friends", function(){
console.log(userFriends.find().fetch());
});
In the client, be aware that collection subscriptions are asynchronous by nature (there's network latency on the client, inherent to fetching the documents from the server).
This is why if you console.log your collection content right after Meteor.subscribeing you'll get [], but if you wait until the subscription is ready using a callback, documents will be displayed correctly.
You have two correct answers but they do assume some knowledge for you. Here's what it looks like using Meteor's file structure (available at http://docs.meteor.com/#/full/structuringyourapp).
In your /lib (shared) directory
Make a file called "collections.js" and in it create your collection.
userFriends = new Mongo.Collection("friends");
I would instead do userFriends = new Mongo.Collection("userfriends"); so that your are always using the same word for your collection and you change the capitalization depending on if you're working on client or server. This is very helpful.
In Your /client directory
Make a file called "subscriptions.js" and in it subscribe to your collection.
Meteor.subscribe('friends');
In Your /server directory
Make a file called "publications.js" and in it publish your collection.
Meteor.publish('friends',function(){
return userFriends.find();
});
You don't need a fetch or anything there.
Essentially your code is failing because of where you're trying to house everything. What I've given you is three points of where you work. Client, Shared, Server. Set your app up that way and it will be easy to immediately figure out where you're working.
Hope that helps.

Flex: recover from a corrupt local SharedObject

My Flex app uses local SharedObjects. There have been incidents of the Flash cookie getting corrupt, for example, due to a plugin crash. In this case SharedObjects.getLocal will throw an exception (#2006).
My client wants the app to recover gracefully: if the cookie is corrupt, I should replace it with an empty one.
The problem is, if SharedObject.getLocal doesn't return an instance of SharedObject, I've nothing to call clear() on.
How can I delete or replace such a cookie?
Many thanks!
EDIT:
There isn't much code to show - I access the local cookie, and I can easily catch the exception. But how can I create a fresh shared object at the same location once I caught the exception?
try {
localStorage = SharedObject.getLocal("heywoodsApp");
} catch (err:Error) {
// what do I do here?
}
The error is easily reproduced by damaging the binary content of a Flash cookie with an editor.
I'm not really sure why you'd be getting a range error - esp if you report that can find it. My only guess for something like this is there is a possibility of crossing boundries with respect to the cross-domain policy. Assuming IT has control over where the server is hosted, if the sub-domain ever changed or even access type (from standard to https) this can cause issues especially if the application is ongoing (having been through several releases). I would find it rather hard to believe that you are trying to retrieve a named SO that has already been named by another application - essentially a name collision. In this regard many of us still uses the reverse-dns style naming convention even on these things.
If you can catch the error it should be relatively trivial to recover from: - just declare the variable outside the scope of the try so it's accessible to catch as well. [edit]: Since it's a static method, you may need to create a postfix to essentially start over with a new identifier.
var mySO:SharedObject;
....
catch(e:Error)
{
mySO = SharedObject.getLocal('my.reversedns.so_name_temp_name');
//might want to dispatch an error event or rethrow a specific exception
//to alert the user their "preferences" were reset.
}
You need to be testing for the length of SharedObject and recreate if it's 0. Also, always use flush to write to the object. Here's a function we use to count the number of times our software is launched:
private function usageNumber():void {
usage = SharedObject.getLocal("usage");
if (usage.size > 0) {
var usageStr:String = usage.data.usage;
var usageNum:Number = parseInt(usageStr);
usageNum = usageNum + 1;
usageStr = usageNum.toString();
usage.data.usage = usageStr;
usage.flush();
countService.send();
} else {
usage.data.usage = "1";
usage.flush();
countService.send();
}
}
It's important to note that if the object isn't available it will automatically be recreated. That's the confusing part about SharedObjects.
All we're doing is declaring the variable globally:
public var usage:SharedObject;
And then calling it in the init() function:
usage = SharedObject.getLocal("usage");
If it's not present, then it gets created.

PopUpWindow and null object reference

I've been struggling with this problem for last few hours but still got no idea what's wrong. Here's the scenario:
Application built on top of the Mate framework sometimes need to exchange data with remote server over plain binary socket.
When specific packet is received I have to switch view (using ViewStack) and create custom panel (using PopUpManager class). This custom panel contains a dataGrid component which has to be populated with some XML received along with mentioned packet.
Trouble is that when I try to assign XML to DataGrid's dataProvider I constantly get "Cannot access a property or method of a null object reference" error. The only thing I can think of is some kind of race when processing events and creating components.
Here are the most interesting pieces of code:
<!-- LoginEvent.LOGIN_OK _____________________________________________________________________ -->
<EventHandlers type="{LoginEvent.LOGIN_OK}">
<MethodInvoker generator="{UserManager}" method="storeCurrentUser" arguments="{event.fullName}"/>
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.MAIN}"/>
<MethodInvoker generator="{CustomSocket}" method="listBoards"/>
In the above code I react when the LOGIN_OK packet is received.
Store user's data, change the view and ask the Socket class wrapper to send request (the reponse for that request is our verySpecificPacket)
Here's detailed info about how I change the view and create custom pop up. In MainUI.mxml:
<mate:Listener type="{NavigationEvent.MAIN}" method="handleNavigationEvent" />
private function launchBoardListWindow():void {
Logger.info("launchBoardListWindow()");
var win:BoardList = PopUpManager.createPopUp(this, BoardList, true) as BoardList;
PopUpManager.centerPopUp(win);
}
private function handleNavigationEvent(event:NavigationEvent):void {
viewStack.selectedIndex = MAIN;
launchBoardListWindow();
}
The third position in EventMap isn't important, it just ask socket wrapper to send some kind of packet. The server is supposed to respond with verySpecialPacket along with XML payload. And here we are at the part where the error is. In mxml describing my custom panel I set up a listener for an event which is being dispatched after my verySpecialPacket is received.
public function handleListBoardsEvent(e:ListBoardsEvent):void {
Logger.info("handleListBoardsEvent");
xmlData = e.xml;
boardList.dataProvider = xmlData.children(); // Here's the error!!!
}
I really don't get it, since the xmlData is OK, and custom panel with all child components were created. Thanks for reading!
You're likely on the right track in respect of a race condition.
Suggestion:
Put a try { ... } catch (e:Error) { trace("error"); } block around the code in your handleListBoardsEvent() method.
Then, put a breakpoint on the trace() and, when it hits, take a good look around at the various objects involved.
My guess is that you're attempting to access the boardList object before it is created - i.e. it's null.
The other possibility is that boardList.dataProvider is a setter and there's code in the setter that's barfing. (Although, if that were the case, I'm sure you would have noticed the stacktrace inFlexBuilder)

Resources