Flex

01
Jan

Java-client for FlexMonkey and Java-style LocalConnection

Posted by eugene as Flex

I think that in many teams, one way or another with the development of Flex applications, soon or late there appears a question about the automated testing of the product. And as our team develops AIR-client for online poker, quite naturally such a question arose in our country.

At first it worked exclusively by the QA team, they have considered some tools including FlexMonkey. In particular, this article hasn’t been disregarded on Habr.

The testing cycle icludes adding of the table though via the administration panel, the registration process on the website followed by the download, installing and running the client. Selenium Test cases have been written for it in Java. What to do next was unclear as the standard FlexMonkey plugin for Selenium (FlexMonkium) can work only with the Flex applications working in the browser, in Flex plugin as it’s written in JS and interacts with Flash via ExternalInterface which is absent in AIR Runtime. In turn, the standard FlexMonkey console interacts with any Flex application including AIR through the purely Flash LocalConnection technology, there didn’t exist any Java realization before. Now it exists.

It was decided to write a client for FlexMonkey in Java, the estimate has been held and I started to work. Let me just specify something, on the 19th of July after the completion of major work on our library new generation of FlexMonkey framework (now called MonkeyTalk) appeared and after the cursory inspection problems with “cross-technologism” seemed to be eliminated by organization the client-agent via socket, but I’m happy with the acquired experience and I think that we’ll continue to develop this product based on the old architecture of GorillaLogic.

Prologue

So, first of all we need to understand what is LocalConnection and how to work with it. All over the web there is only one source which describes, though not fully, the interns of LocalConnection and the information is a bit outdated. Here’s the article.

What can we see from the article

The LocalConnection is the Memory File Mapping object with the size of 65,535 bytes which has the MacromediaFMOmega name and the exclusive access to it is provided by capturing mutex with the MacromediaMurexOmega name. Here’s the example map of the memory area:

As you can see from the map, in this protocol the AMF coding of both versions is fully used. AMF (Action Message Format) is the binary data representation protocol developed by Adobe. The specificaton is available here, and here for AMF3.

IN general case the process of receiving the message looks as follows:

  • 1. Registering the listener by adding its name into the chain
  • 2. Capturing mutex
  • 3. Getting file mapping and checking the receiver
  • 4. If you are the receiver, read the message and zero out timestamp and length, this way we mark the message as read
  • 5. Repeat infinitely starting from the 2nd step

The process of recording the message looks as follows:

  • 1. Capturing mutex
  • 2. Getting file mapping and repeat if receiver exists which we should send the message
  • 3. Recording the message
  • 4. Releasing file mapping and mutex

Java part

As normal means are absent in the standard Java library for working with Memory File Mapping, it was considered to write the native JNI library for working with this technology. The library has been written in C++ in Visual Studio Express 2010 and built under the 32-bit architecture. It contains the methods for creation/capturing/releasing of mutex, creation/getting/releasing of the file mapping object and recording/reading in/from it, and wrapper under WinAPI by the GetTickCount() function which is necessary for receiving the timestamp.

Further the LocalConnection Java class has been written which fully recalls the interface of its Flash brother excluding the events. It has the setClient() method which applies the class instance that implements the LocalConnectionSink interface where the onInvoke method is defined (String method, Object… args), receiving the inbound calls by the name of the target method with its parameters. The send() method recalls such from Flash, applies the connection name, method name which needs to be called, its parameters and puts all this into the sending queue.

The separate thread is working in the class itself which adds listener/reads the message, checks the receiver/records the message. When receiving new message – restarts the onInvoke() client method. The corresponding library from BlazeDS is used in/from AMF as a serializer/deserializer. All is pretty simple.

Then we had to adjust the message with the automation agent of FlexMonkey in our application. It’s connected to the project by adding the SWC library and the MonkeyLink class serves an input point in it, the protocol is called exactly the same. On the agent side it registers endpoint with the “_agent” name, the client from its side should be registered with the “_flexMonkey” name. This class contains several public methods. The “ping” method serves for the symmetric pinging of client/agent one time per half of second. At the time of its call the isConnected flag is set that tetstifies that the opposite side is alive yet and it receives the messages. This flag is reset by timer, one time per 5 seconds.

Also this class contains a row of methods which accept the successor instances of the MonkeyRunnable class. These are the commands representing actions which we see on the control panel of the classic FlexMonkey console.

Hence Java analogue of this class has been developed and the Java analogues of the FlexMonkey commands from ActionScript as well. These are such commands as SetProperty, CallFunction, VerifyProperty, UIEvent and so on. This class contains the playCommand() method which accepts the command instance with the necessary parameters, serializes it and sends to the agent via LocalConnection.

Also this class contains two additional threads – the first sends ping to the agent one time per half of second, and the second thread resets the IsConnected flag one time per 5 second.

The wrapper in the view of the FlexMonkeyAutomator has been made out of it which represents simple API into direction of QA engineer for the synchroneous call of actions on the agent. Also you can specify the amount of action call attempts and the delay between them. In the general case the work session with the testing application looks as follows:

MonkeyLink monkeyLink = new MonkeyLink();
if (monkeyLink.startLink(2000)) { // Соединяемся с агентом, таймаут 2 секунды
    FlexMonkeyAutomator flexMonkeyAutomator = new FlexMonkeyAutomator(monkeyLink);
    flexMonkeyAutomator.setProperty(...
    flexMonkeyAutomator.storeValue(...
    flexMonkeyAutomator.uiEvent(...
    flexMonkeyAutomator.verifyProperty(...
    flexMonkeyAutomator.callFunction(...
 
    monkeyLink.disconnect();
}

All the FlexMonkeyAutomator methods contain the overloaded versions applying timeout by the last parameter. This is useful, in particular in this case: in the last action we press the Exit from Application button, the application shuts and it doesn’t have time to send the action result, in this case the general action call method version will never return the management and our test-script will not complete, but the version with the timeout will complete successfully.

All the sources of this library are available at BitBucket. Please don’t take seriously the JMonkeyLinkTest seriously which contains the testing Swing application with the huge “shitty” code – it is indended exclusively for the situative testing of separate library features, and the general testing lead our QA’s on the fighting scripts.

PS: Almost forgot. Nevertheless while serializing the commands on the Java side, I assign PQDN to them corresponding to their PQDN, for some reason they deserialize all the same into general Object, that’s why they should be registered via registerClassAlias() in the testing application:

registerClassAlias("com.gorillalogic.flexmonkey.monkeyCommands.CallFunctionMonkeyCommand", CallFunctionMonkeyCommand);

And I hope this product will carry use to somebody, and also will be useful for those who wants to build the interaction between Java- and Flash/Flex code in the own project by means of LocalConnection. Thank you for attention.

26
Sep

What is BlazeDS

Posted by eugene as Flex

Developing RIA application in Flex, the http server should be used for data processing. For these purposes the usual Apache server (with the installed PHP) will be suitable. The communication of the server and client sides will be carried out via the HTTP requests where data will be transmitted in XML or JSON.

The Flash technology has its own data transfer format – AMF3. The described above configuration can be worked up for supporting this format by installing the AMFPHP library on Apache.

The problem is that PHP language is enough for small applications. But if you plan to create a larger system, you need to think about switching to a more suitable language for it – such as Java. In addition, a great server exists for the interaction of programs in this language with the Flex clients – BlazeDS.

BlazeDS is the web application that is run in servlet container or Java application server. BlazeDS is a set of services that are managed through the JMX agent. Its features are as follows:

  • Implements the removed Java methods by request of the Flex application.
  • Translates Java objects into AS3 objects while returning the result of implementing of Java method.
  • Translates AS3 objects into Java objects while calling the removed Java method from the Flex application.
  • Serves teh connections between Flex application and Java application.
  • Delivers data on the client without a request.

The articles which will describe the creation of RIA applications in details by using BlazeDS will appear on the blog soon.

23
Jul

PHP and FileReference in Flex

Posted by eugene as Flex, PHP

Authentication is necessary in any RIA application. Good it’s that making it is easy. The most common authentication is carried out on the server side and its results are recorded into the session parameters. It allows the user to request the authorization data only once for the entire work session with the application.

In conjunction of Flex and PHP, such a scheme works without any problem. All requests on the server side can be protected by authorization data in the PHP session. But if you try to check the authentication in the POST request of the file load handler from FileReference, it won’t work out. The session will be empty in the request handler.

The PHP session is getting connected with the browser session ID which is stored in the browser cookies. The problem is that when you request via FileReference cookies are not transmitted. As a result, PHP opens a new session.

To let PHP use an existing session, it is necessary to add the ID parameter to the current session. For example:

public function browse():void
{
	fileReference = new FileReference();
	fileReference.addEventListener(Event.SELECT, onDocumentSelected);
	fileReference.browse();
}
 
private function onDocumentSelected(event:Event):void
{
	getSession();
}
 
private function sessionRecieved(sessionId:String):void
{
	var url:String = "http://example.com?PHPSESSID=" + sessionId;
	var urlRequest:URLRequest = new URLRequest(url);
	fileReference.upload(urlRequest);
}

In the example, in the document selection handler the getSession() method is called which is requesting the session identifier from the PHP side. When the ID is received, the sessionReceived method is called which places the session IDs into the query line and initiates the file download. The session identifier is placed into the PHPSESSID parameter.

Also the identifier of the PHP session can be requested via JavaScript. But I do not like this option.

04
Jul

Flex. Should ItemRenderer know the model type?

Posted by eugene as Flex

Let’s begin from the thing if you like to develop using a strongly typified programming language or the untypified one. In the latter case, there’s no sense to read the article further. If you, like me, prefer strong typification then let’s think about…

As you may know, in order to display data there’s a type of the data variable in ItemRenderer. The problem is that the type of the variable – Object. And it’s not acceptable if all the models in the project are typified.

I think that the data variable should contain the type of the processing object in ItemRenderer. It will allow to avoid disappointing mistakes while refactoring – you will know about them right before launching the program, on the compilation level. And this, as you understand, costs high.

That’s why I suggest to use the typified variables of the displaying data in all ItemRender’s. For example, I do the following:

 
    {data}