Adobe AIR HTTP Connection Limit

2019-07-31 01:42发布

I'm working on an Adobe AIR application which can upload files to a web server, which is running Apache and PHP. Several files can be uploaded at the same time and the application also calls the web server for various API requests.

The problem I'm having is that if I start two file uploads, while they are in progress any other HTTP requests will time out, which is causing a problem for the application and from a user point of view.

Are Adobe AIR applications limited to 2 HTTP connections, or is something else probably the issue? From searching about this issue I've not found much but one article did indicated that it wasn't limited to just two connections.

The file uploads are performed by calling the File classes upload method, and the API calls are done using the HTTPService class. The development web server I am using is a WAMP server, however when the application is released it will be talking to a LAMP server.

Thanks, Grant

Here is the code I'm using to upload the file:

protected function btnAddFile_clickHandler(event:MouseEvent):void
{
    // Create a new File object and display the browse file dialog
    var uploadFile:File = new File();
    uploadFile.browseForOpen("Select File to Upload");
    uploadFile.addEventListener(Event.SELECT, uploadFile_SelectedHandler);
}

private function uploadFile_SelectedHandler(event:Event):void
{
    // Get the File object which was used to select the file
    var uploadFile:File = event.target as File;
    uploadFile.addEventListener(ProgressEvent.PROGRESS, file_progressHandler);
    uploadFile.addEventListener(IOErrorEvent.IO_ERROR, file_ioErrorHandler);
    uploadFile.addEventListener(Event.COMPLETE, file_completeHandler);

    // Create the request URL based on the download URL
    var requestURL:URLRequest = new URLRequest(AppEnvironment.instance.serverHostname + "upload.php");
    requestURL.method = URLRequestMethod.POST;

    // Set the post parameters
    var params:URLVariables = new URLVariables(); 
    params.name = "filename.ext";
    requestURL.data = params;

    // Start uploading the file to the server
    uploadFile.upload(requestURL, "file");
}

Here is the code for the API calls:

private function sendHTTPPost(apiFile:String, postParams:Object, resultCallback:Function, initialCallerResultCallback:Function):void
{
    var httpService:mx.rpc.http.HTTPService = new mx.rpc.http.HTTPService();
    httpService.url = AppEnvironment.instance.serverHostname + apiFile;
    httpService.method = "POST";
    httpService.requestTimeout = 10;
    httpService.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
    httpService.addEventListener("result", resultCallback);
    httpService.addEventListener("fault", httpFault);
    var token:AsyncToken = httpService.send(postParams);

    // Add the initial caller's result callback function to the token
    token.initialCallerResultCallback = initialCallerResultCallback;
}

3条回答
乱世女痞
2楼-- · 2019-07-31 01:46

So as I was looking into this, I came across this info about using File.upload() in the documentation:

Starts the upload of the file to a remote server. Although Flash Player has no restriction on the size of files you can upload or download, the player officially supports uploads or downloads of up to 100 MB. You must call the FileReference.browse() or FileReferenceList.browse() method before you call this method.

Listeners receive events to indicate the progress, success, or failure of the upload. Although you can use the FileReferenceList object to let users select multiple files for upload, you must upload the files one by one; to do so, iterate through the FileReferenceList.fileList array of FileReference objects.

The FileReference.upload() and FileReference.download() functions are nonblocking. These functions return after they are called, before the file transmission is complete. In addition, if the FileReference object goes out of scope, any upload or download that is not yet completed on that object is canceled upon leaving the scope. Be sure that your FileReference object remains in scope for as long as the upload or download is expected to continue.

I wonder if something there could be giving you issues with uploading multiple files. I see that you are using browserForOpen() instead of browse(). It seems like the probably do the same thing... but maybe not.

I also saw this in the File class documentation

Note that because of new functionality added to the Flash Player, when publishing to Flash Player 10, you can have only one of the following operations active at one time: FileReference.browse(), FileReference.upload(), FileReference.download(), FileReference.load(), FileReference.save(). Otherwise, Flash Player throws a runtime error (code 2174). Use FileReference.cancel() to stop an operation in progress. This restriction applies only to Flash Player 10. Previous versions of Flash Player are unaffected by this restriction on simultaneous multiple operations.

When you say that you let users upload multiple files, do you mean subsequent calls to browse() and upload() or do you mean one call that includes multiple files? It seems that if you are trying to do multiple separate calls that that may be an issue.

Anyway, I don't know if this is much help. It definitely seems that what you are trying to do should be possible. I can only guess that what is going wrong is perhaps a problem with implementation. Good luck :)

Reference: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#upload()

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#browse()

查看更多
Root(大扎)
3楼-- · 2019-07-31 01:51

Just because I was thinking about a very similar question because of an error in one of my actual apps, I decided to write down the answer I found.

I instantiated 11

HttpConnections

and was wondering why my Flex 4 Application stopped working and threw an HTTP-Error although it was working pretty good formerly with just 5 simultanious HttpConnections to the same server.

I tested this myself because I did not find anything regarding this in the Flex docs or on the internet.

I found that using more than 5 HTTPConnections was the reason for the Flex application to throw the runtime error.

I decided to instantiate the connections one after another as a temporally workaround: Load the next one after the other has received the data and so on. Thats of course just temporally since one of the next steps will be to alter the responding server code in that way that it answers a request that contains the results of requests to more then one table in one respond. Of course the client application logic needs to be altered, too.

查看更多
Root(大扎)
4楼-- · 2019-07-31 02:03

If you are on a windows system, Adobe AIR is using Microsofts WinINet library to access the web. This library by default limits the number of concurrent connections to a single server to 2:

WinInet limits the number of simultaneous connections that it makes to a single HTTP server. If you exceed this limit, the requests block until one of the current connections has completed. This is by design and is in agreement with the HTTP specification and industry standards.

... Connections to a single HTTP 1.1 server are limited to two simultaneous connections

There is an API to change the value of this limit but I don't know if it is accessible from AIR.

Since this limit also affects page loading speed for web sites, some sites are using multiple DNS names for artifacts such as images, javascripts and stylesheets to allow a browser to open more parallel connections.

So if you are controlling the server part, a workaround could be to create DNS aliases like www.example.com for uploads and api.example.com for API requests.

查看更多
登录 后发表回答