AS3 LocalConnection: function is not firing - actionscript-3

I'm building an AIR app that sends text string to a swf-file. When I export the sender and reciever apps to swf and run them in Flash players, everything works well. But when publishing the sender app to AIR things don't work anymore.
I think the connection works, because there are no error messages. But the function on reciever swf won't fire.
Here's my code for AIR (the sender):
import flash.net.LocalConnection;
import flash.events.MouseEvent;
var conn:LocalConnection;
conn = new LocalConnection();
conn.addEventListener(StatusEvent.STATUS, onLocalConnError);
function send_it(event:MouseEvent):void
{
conn.send('_connection', 'fire','myString');
}
function onLocalConnError(e:StatusEvent):void
{
teksti.text = e.toString();
}
btn.addEventListener(MouseEvent.CLICK, send_it);
And the reciever SWF:
import flash.net.LocalConnection;
import flash.events.MouseEvent;
var conn:LocalConnection;
function connect(event:MouseEvent):void
{
conn = new LocalConnection();
conn.addEventListener(StatusEvent.STATUS, onLocalConnError);
conn.allowDomain("app#fi.myapp");
conn.client = this;
conn.connect('_connection');
this.addEventListener(Event.CLOSE, closeConnection);
}
btn.addEventListener(MouseEvent.CLICK, connect);
function onLocalConnError(e:StatusEvent):void
{
my_text.text = e.toString();
}
function fire(txt:String):void
{
my_text.text = txt;
}
function closeConnection(e:Event = null):void
{
conn.close();
}
Any ideas what I'm doing wrong?

You have to identifier the receiving app PLUS the connectionname in the send-call:
conn.send('app#YourReceivingAppName:_connection', 'fire','myString');
Greetings

Related

AS3 URLLoader POST aborted in browser

I've re-built an SWF audio uploader, and it was working fine for a few days. However, I just did a run-through of all the things I've built onto this project, and I notice that the POST request to the server to save the audio file is being Aborted about 10 seconds into the request. At 20 seconds, everything stops because of a timeout limitation that is implemented. I don't know much about AS3 or how it makes requests, but I do know that the PHP handler file is solid because no changes were made to it from the point which it worked last. The permissions are 755 and ownerships are correct on both the SWF and the handler file. I can also re-submit the request via Firebug, and it works with no issue whatsoever.
I'm not sure where the problem is stemming from exactly; whether it be browser, server or code issue. I was reading about Aborted requests and I've ensured that there are no other active requests before trying to upload. I should also add that other POST/GET requests have no issues, it's just this one request from the SWF.
Again, Flash/ActionScript is not a strength of mine, so if there are ways to improve what I'm doing, or if anyone can tell me what I'm doing wrong, please tell me.
package{
import flash.display.Sprite;
import flash.media.Microphone;
import flash.system.Security;
import org.bytearray.micrecorder.*;
import org.bytearray.micrecorder.events.RecordingEvent;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.ActivityEvent;
import fl.transitions.Tween;
import fl.transitions.easing.Strong;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.display.LoaderInfo;
import flash.external.ExternalInterface;
import flash.media.Sound;
import org.as3wavsound.WavSound;
import org.as3wavsound.WavSoundChannel;
import com.adobe.serialization.json.JSON;
import com.adobe.serialization.json.JSONDecoder;
public class Main extends Sprite{
private var mic:Microphone;
private var requestor:URLLoader;
private var waveEncoder:WaveEncoder = new WaveEncoder();
private var recorder:MicRecorder = new MicRecorder(waveEncoder);
private var recBar:RecBar = new RecBar();
private var maxTime:Number = 30;
private var tween:Tween;
private var fileReference:FileReference = new FileReference();
private var tts:WavSound;
public function Main():void{
trace('recoding');
recButton.visible = false;
activity.visible = false ;
godText.visible = false;
recBar.visible = false;
mic = Microphone.getMicrophone();
mic.setSilenceLevel(5);
mic.gain = 50;
mic.setLoopBack(false);
mic.setUseEchoSuppression(true);
Security.showSettings("2");
requestor = new URLLoader();
addListeners();
}
private function addListeners():void{
recorder.addEventListener(RecordingEvent.RECORDING, recording);
recorder.addEventListener(Event.COMPLETE, recordComplete);
activity.addEventListener(Event.ENTER_FRAME, updateMeter);
//accept call from javascript to start recording
ExternalInterface.addCallback("startRecording", startRecording);
ExternalInterface.addCallback("stopRecording", stopRecording);
ExternalInterface.addCallback("sendFileToServer", sendFileToServer);
}
//external java script function call to start record
public function startRecording(max_time):void{
maxTime = max_time;
if(mic != null){
recorder.record();
ExternalInterface.call("$.audioRec.callback_started_recording");
}else{
ExternalInterface.call("$.audioRec.callback_error_recording", 0);
}
}
//external javascript function to trigger stop recording
public function stopRecording():void{
recorder.stop();
mic.setLoopBack(false);
ExternalInterface.call("$.audioRec.callback_stopped_recording");
}
public function sendFileToServer():void{
finalize_recording();
}
public function stopPreview():void{
//no function is currently available;
}
private function updateMeter(e:Event):void{
ExternalInterface.call("$.audioRec.callback_activityLevel", mic.activityLevel);
}
private function recording(e:RecordingEvent):void{
var currentTime:int = Math.floor(e.time / 1000);
ExternalInterface.call("$.audioRec.callback_activityTime", String(currentTime));
if(currentTime == maxTime ){
stopRecording();
}
}
private function recordComplete(e:Event):void{
preview_recording();
}
private function preview_recording():void{
tts = new WavSound(recorder.output);
tts.play();
ExternalInterface.call("$.audioRec.callback_started_preview");
}
//function send data to server
private function finalize_recording():void{
var _var1:String= '';
var globalParam = LoaderInfo(this.root.loaderInfo).parameters;
for(var element:String in globalParam){
if(element == 'host'){
_var1 = globalParam[element];
}
}
ExternalInterface.call("$.audioRec.callback_finished_recording");
if(_var1 != ''){
ExternalInterface.call("$.audioRec.callback_started_sending");
var req:URLRequest = new URLRequest(_var1);
req.contentType = 'application/octet-stream';
req.method = URLRequestMethod.POST;
req.data = recorder.output;
requestor.addEventListener(Event.COMPLETE, requestCompleteHandler);
requestor.load(req);
}
}
private function requestCompleteHandler(event:Event){
ExternalInterface.call("$.audioRec.callback_finished_sending", requestor.data);
}
private function getFlashVars():Object{
return Object(LoaderInfo(this.loaderInfo).parameters);
}
}
}

Receiving a stream of a NetGroup

I'm trying to receive a stream of a NetGroup (television) but it fails at some point. Here is the code (reduced to a testcase):
package lib
{
import flash.events.NetStatusEvent;
import flash.external.ExternalInterface;
import flash.media.SoundTransform;
import flash.media.Video;
import flash.net.GroupSpecifier;
import flash.net.NetConnection;
import flash.net.NetGroup;
import flash.net.NetStream;
import flash.net.NetStreamPlayOptions;
import mx.core.FlexGlobals;
public class player
{
private var connection:NetConnection;
private var group:NetGroup;
private var group_option:GroupSpecifier;
private var self:Object;
private var stream:NetStream;
private var stream_option:NetStreamPlayOptions;
private var video:Video;
private function _connect():void
{
self.connection = new NetConnection();
self.connection.addEventListener(NetStatusEvent.NET_STATUS, self._event_net_status);
self.connection.connect('rtmfp://p2p.peer-stream.com');
}
private function _event_net_status(event:NetStatusEvent):void
{
if(event.info.code === '')
return;
ExternalInterface.call('echo', 'status', event.info.code, false);
switch(event.info.code)
{
case 'NetConnection.Connect.Success':
self._p2p_start();
break;
case 'NetGroup.Connect.Success':
self._stream_init();
break;
case 'NetStream.Connect.Success':
self._stream_start();
break;
}
}
private function _p2p_start():void
{
self.group_option = new GroupSpecifier('G:0101010c0b0e70726f2073696562656e00');
self.group_option.ipMulticastMemberUpdatesEnabled = true;
self.group_option.multicastEnabled = true;
self.group_option.objectReplicationEnabled = true;
self.group_option.postingEnabled = true;
self.group_option.routingEnabled = true;
self.group_option.serverChannelEnabled = true;
self.group = new NetGroup(self.connection, self.group_option.groupspecWithAuthorizations());
self.group.addEventListener(NetStatusEvent.NET_STATUS, self._event_net_status);
}
private function _stream_init():void
{
self.stream = new NetStream(self.connection, self.group_option.groupspecWithAuthorizations());
self.stream.addEventListener(NetStatusEvent.NET_STATUS, self._event_net_status);
}
private function _stream_start():void
{
self.video.attachNetStream(self.stream);
self.stream.soundTransform = new SoundTransform();
self.stream_option = new NetStreamPlayOptions();
self.stream_option.streamName = 'G:0101010c0b0e70726f2073696562656e00';
self.stream.play2(self.stream_option);
}
public function player():void
{
super();
FlexGlobals.topLevelApplication.stage.quality = 'BEST';
self = this;
self.video = new Video(640, 480);
FlexGlobals.topLevelApplication.video_box.addChild(self.video);
self.video.smoothing = true;
self._connect();
}
}
}
The ExternalInterface call there shows me just the passed info in a textfield (I'm testing this in a browser). Here is the result of this output:
NetConnection.Connect.Success
NetGroup.Connect.Success
NetStream.Connect.Success
NetStream.Play.Reset
NetStream.Play.Start
But nothing happens on the player. Here are my thoughts:
I'm using the same string as GroupSpecifier and streamName but I'm assuming this is wrong. If so how can I get the stream name of the NetGroup?
I'm enabling everything from the GroupSpecifier as I don't know what are the minimum requirements to receive a stream and pass it then to another clients. Maybe enabling all makes some troubles here.
Maybe somebody can tell me how I can solve this problem to finally see a stream.
I was able to solve the problem: The streamName was indeed wrong and I could manually figure out the correct name. Also instead of using new GroupSpecifier() I must pass the known group-string directly to the NetGroup and NetStream object.

fileReference.save; works in swf but doesn't work when the swf embeded in the html

This code works properly when published by Flash CS 5.5 as .swf (it prompts to browse where to save the file). However, when it is published to HTML, it doesn't work (doesn't prompt to browse the destination). Is it security issue or other problem?
import flash.display.Sprite;
import flash.media.Microphone;
import flash.system.SecurityDomain;
import org.bytearray.micrecorder.*;
import org.bytearray.micrecorder.events.RecordingEvent;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import flash.events.Event;
import flash.net.FileReference;
import flash.utils.setTimeout;
var mic:Microphone;
var waveEncoder:WaveEncoder = new WaveEncoder();
var recorder:MicRecorder = new MicRecorder(waveEncoder);
var fileReference:FileReference = new FileReference();
mic = Microphone.getMicrophone();
mic.setSilenceLevel(0);
mic.gain = 100;
mic.setLoopBack(true);
mic.setUseEchoSuppression(true);
Security.showSettings("2");
addListeners();
function addListeners():void
{
setTimeout(startIntroTime,3000);
function startIntroTime():void
{
startRecording();
setTimeout(stopRecording,5000);
}
recorder.addEventListener(Event.COMPLETE, recordComplete);
}
function startRecording():void
{
if (mic != null)
{
recorder.record();
}
}
function stopRecording():void
{
recorder.stop();
mic.setLoopBack(false);
}
function recordComplete(e:Event):void
{
fileReference.save(recorder.output, "recording.wav");
}
Have a look at the documentation: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#save()
It says :
In Flash Player, you can only call this method successfully in response to a user event (for example, in an event handler for a mouse click or keypress event). Otherwise, calling this method results in Flash Player throwing an Error exception. This limitation does not apply to AIR content in the application sandbox.
So it is not possible and probably a security thing.

ActionScript throwing Error #1009 when calling addChild with a TileList as the argument

To be exact this is the error.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at fl.containers::BaseScrollPane/drawBackground()
at fl.controls::TileList/draw()
at fl.core::UIComponent/callLaterDispatcher()
Now I've tried several of Adobe's own examples from this page, http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/fl/controls/TileList.html, and they all throw this error as well.
The error is triggered by the TileList instance being the argument of the addChild function.
Here's my package, which works fine when I change the displayComponent is be a List.
package com.pennstate {
import fl.data.DataProvider;
import flash.display.MovieClip;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextFormat;
import flash.xml.XMLDocument;
import com.adobe.serialization.json.JSON;
import fl.controls.List;
import fl.controls.TileList;
public class Sign {
public var displayComponent:TileList;
public var url:String;
public var provider:DataProvider;
public var mc:MovieClip;
public var container:DisplayObjectContainer;
public function Sign( url:String, container ) {
this.container = container;
this.displayComponent = new TileList();
this.mc = new MovieClip();
this.url = url;
this.provider = new DataProvider();
_componentSetup();
loadJson();
_componentFormat();
}
private function _componentSetup() {
displayComponent.labelFunction = getLabelFieldContent;
displayComponent.sourceFunction = getSourceFieldContent;
displayComponent.dataProvider = provider;
displayComponent.selectable = false;
displayComponent.setStyle("contentPadding", 5);
displayComponent.setSize(1720,770);
displayComponent.move(100,200);
displayComponent.rowHeight = 190;
trace('End setup');
}
private function _componentFormat() {
var listTextFormat:TextFormat = new TextFormat();
listTextFormat.font = "Arial";
listTextFormat.color = 0x000000;
listTextFormat.bold = true;
listTextFormat.size = 48;
displayComponent.setRendererStyle("textFormat", listTextFormat);
trace('End formatting');
}
function loadJson():void {
var jsonLoader:URLLoader = new URLLoader();
jsonLoader.addEventListener(Event.COMPLETE, onJsonComplete);
jsonLoader.load( new URLRequest( url ) );
}
function onJsonComplete(e:Event):void {
trace('Loading finished.');
var jsonData:String = e.target.data;
trace(jsonData + "\n");
var decodedData = JSON.decode(jsonData, false);
for (var index in decodedData.rows) {
provider.addItem({title: decodedData.rows[index].node.title, result: decodedData.rows[index].node.Result});
trace(index+" => "+decodedData.rows[index].node.title);
trace(index+" => "+decodedData.rows[index].node.Result);
}
container.addChild(displayComponent);
}
function getLabelFieldContent(item:Object):String {
return new XMLDocument(item.title + "\n" + item.result).firstChild.nodeValue;
}
function getSourceFieldContent(item:Object):String {
return item.result;
}
}
}
You have not given your container agrument in the constructor a type i.e: UIComponent
public function Sign( url:String, container:UIComponent )
This coupled with the fact that its the same name as your member variable is probably the cause.
I had to drag an actual TileList component from the Component Menu onto the Stage using the Flash CS4 GUI to make this error go away.
The weird part is the component that I dragged onto the Stage isn't the component I use in the code. The component I created dynamically in the code now works though.
I even deleted the TileList component that I added to the Stage and it still works. This sounds like a bug to me.

The right way to send variables with as3 to asp?

Im trying to make an swf send a phone-number to a specific asp-fil on the press of a button.
But since I'm an as3 rookie I have no idea where this code is going wrong (PLEASE HELP):
import flash.events.IOErrorEvent;
import flash.display.*;
import flash.events.MouseEvent;
import flash.net.*;
import flash.events.Event;
public class action extends MovieClip
{
private var swf_front_mc:swf_front = new swf_front ;
var request:URLRequest = new URLRequest("succes.html");
var request2:URLRequest = new URLRequest("http://www.example.com");
public var mobilNr:Number = new Number(swf_front_mc.mobilInput.text);
public var varsToSend:URLVariables = new URLVariables();
public function action()
{
addChild(swf_front_mc);
swf_front_mc.name = "swf_front_mc";
swf_front_mc.x = 0;
swf_front_mc.y = 0;
makeInteraction();
}
private function makeInteraction():void
{
swf_front_mc.submit_mc.addEventListener(MouseEvent.CLICK, submitForm);
}
function submitForm(e:MouseEvent):void
{
//trace("hello");
varsToSend.RecipientMobileNumber = mobilNr;
// Create URL Request, set to POST, and attach data
var formRequest:URLRequest = new URLRequest("webform_input.asp");
formRequest.method = URLRequestMethod.GET;
formRequest.data = varsToSend;
// Create URL Loader, attach listeners, and load URL Request
var varLoader:URLLoader = new URLLoader ;
varLoader.addEventListener(Event.COMPLETE, onLoaded);
varLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
varLoader.load(formRequest);
}
function onLoaded(e:Event):void
{
navigateToURL(request,"blank");
}
function ioErrorHandler(e:IOErrorEvent):void
{
navigateToURL(request2,"blank");
}
}
Thanks for the tips and hints guys...
Meanwhile i got the perfect solution from a friend. It's much shorter and more simple then I thought possible. Here it is:
package app.form
{
import flash.net.*;
import flash.display.*;
import flash.events.*;
public class container extends MovieClip
{
public function container()
{
sendBtn.addEventListener(MouseEvent.CLICK, sendBtnClick);
}
public function SendToURLExample(_navn:String, _tlf:String) {
var url:String = "http://www.yourdomain.com/file.asp";
var variables:URLVariables = new URLVariables();
variables.name = _name;
variables.phone = _phone;
var request:URLRequest = new URLRequest(url);
request.data = variables;
trace("sendToURL: " + request.url + "?" + request.data);
try {
sendToURL(request);
}
catch (e:Error) {
// handle error here
}
}
// two text-example-fields on stage called input_text_name/input_text_mobil
private function sendBtnClick(e:MouseEvent):void {
SendToURLExample(input_text_name.text, input_text_mobil.text);
}
}
}
Hope this will solve the something for someone out there :)
try this one example
http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/URLVariables.html#includeExamplesSummary
or you can try to encode your vat into GET URL like new URLRequest("localhost/?number="+numberField.text);
but first one try navigatetourl method from previous sample.
p.s. look at this too: http://blog.flexexamples.com/2007/08/16/using-httpservice-tag-to-sendreceive-variables-to-a-server-side-script/