I am using BackgroundTransferService to download a file from the internet.
pseudo code goes something like this:
BackgroundTransferRequest transferRequest = new BackgroundTransferRequest(transferUri);
transferRequest.Method = "GET";
transferRequest.Tag = "myTag";
transferRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
BackgroundTransferService.Add(transferRequest);
after this, i add an event handler to handle the transfer when it is completed.
I am only using TransferStatusChanged event handler, not TransferProgressChanged
transferRequests = BackgroundTransferService.Requests;
transferRequests.Last().TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferStatusChanged);
under transfer_TransferStatusChanged() i do whatever i want to do with my downloaded file, or handle the failed situations (404 etc).
The problem is that my downloads go on for indefinite time if there is no 404 response from the server (for example when there is no such server, eg. www.googlea.com/myfilename). I want to implement a timeout for such scenario .. how can i do that ?
There is no built in support for such a scenario. You'll have to build in the timeout support yourself.
Be careful of transfering large files though as the transfer could be done in parts and over a very large period of time, depending on connectivity and battery charge level.
Of course, you may want to add a check that a file exists before making the transfer request and if you have any control over the server you should make sure that the correct responses are being sent too.
Related
I have an asp.net mvc website hosted on Windows Server 2012r2 Standard which uses KnockoutJS to display data in a grid. This server is dedicated to the process that I'm having trouble with - it does not server any other requests.
An ajax call is made to a "GetRecords" action of a controller. This returns data for a couple of dozen records very quickly.
The user is able to make amendments to the data and submit for update. The knockout code makes another ajax call, this time posting the records. At this point the site "hangs" for a long time (over 10 minutes), but it does complete successfully and the updated date is persisted to a database. During the "hang time" the CPU for the IIS Worker Processes hovers around the 50% mark.
I'm trying to figure out what's causing the delay. It seems that the delay happens before the first line of code of the controller action is reached. I've added trace statements to the action and I can see that once the 1st line is executed, then the action completes within a couple of seconds.
From the IIS manager, I've drilled in to "Worker Processes"\"Current Requests" during the time the page is "hung", I can see that the State is listed as "ExecuteRequestHandler" and the Module Name is "ManagedPipelineHandler". There are no other "Current Requests" displayed.
Using the Chrome dev tools, I've captured the json being posted for the update, it is approx 4mb in size.
I've ruled out the problem being caused by bandwidth because I've tested from a browser running locally (on the web server), and I get the same delay.
Also, when I post the same number of records on the same site hosted on my dev VM then it works fine - completes end-to-end in under 3 seconds.
Any suggestion on steps I can take to improve performance of the post?
I have created a process dump of the IIS worker process when it is in the "hanging" state, this is available at: onedrive link
It seems that "Thread 28" is causing the issue, since this has a "Time spent in user mode" value of over 2 minutes. I requested the process dump about 2 minutes after making the http post request from the website. The post did eventually complete ok after about 20 minutes
Able to work around this problem bypassing the MVC model binding. The view model param (editBatchVm) that was passed into the controller method has been replaced. So, instead of:
public void ResubmitRejectedVouchersAsNewBatch(EditBatchViewModel editBatchVm)
{
I now have:
public void ResubmitRejectedVouchersAsNewBatch()
{
string requestData = "";
using (var reader = new StreamReader(Request.InputStream))
{
requestData = reader.ReadToEnd();
}
EditBatchViewModel editBatchVm = JsonConvert.DeserializeObject<EditBatchViewModel>(requestData);
Im creating a web extension and porting from XUL. I used to be able to easily read files with
var dJsm = Components.utils.import("resource://gre/modules/Downloads.jsm").Downloads;
var tJsm = Components.utils.import("resource://gre/modules/Task.jsm").Task;
var fuJsm = Components.utils.import("resource://gre/modules/FileUtils.jsm").FileUtils;
var nsiPromptService = Components.classes["#mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
....
NetUtil.asyncFetch(file, function(inputStream, status) {
if (!Components.isSuccessCode(status)) {
return;
}
var data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
var data = window.btoa(data);
var encoded_data_to_send_via_xmlhttp = encodeURIComponent(data);
...
});
This above will be deprecated.
I can use the downloads.download() to know what was the last download but I can NOT read the file and then get the equivalent for encoded_data_to_send_via_xmlhttp
Also in Firefox 57 onwards, means that I have to try to fake a user action by a button click or something, or upload a file.
Access to file:// URLs or reading files without any explicit user input
isnt there an easy way to read the last downloaded file?
The WebExtension API won't allow extensions to read local files anymore. You could let the extension get CORS privilege and read the content directly from the URL via fetch() or XMLHttpRequest() as blob and store directly to IndexedDB or memory, then encode and send to server. This comes with many restrictions and limitations such as to which origin you can read from and so forth.
Also, this would add potentially many unneeded steps. If the purpose is, as it seem to be in the question at the moment, to share the downloaded file with a server, I would instead suggest that you obtain the last DownloadItem object, extract the URL (.url) from that object and send the URL back to server.
This way the server can load directly from that URL (and encode it on server if needed). The network load will be about the same (a little less actually since there is no Base64 encoding involved which adds 33% to the size), and much less load on the client. The server would read the data as a binary/byte data stream; about the same as if the data was sent directly from the extension.
To obtain the last downloaded file you would do the following from a privileged script:
browser.downloads.search({
limit: 1,
orderBy: ["-startTime"]
})
.then(getLastDownload);
function getLastDownload(downloads) {
if (downloads.length) {
var url = downloads[0].url;
// ... send url to the server and let server fetch the data from it directly
}
}
According to this support mozilla question.
(2) Local file security
Firefox limits access from pages on web servers to pages on local disk or UNC paths. [...]).
Which solution ?
Use local-filesystem-links firefox addon (not tested)
and/or
run a small local webserver on client side, supposing server was run with sufficient privileges, you may finally access any local content via http:// (but still cannot with file:///)
My app uses Google API client library for .NET to send emails with attachments.
When using Send(), I'm facing some limitations when it comes to file size of the attachments. So, I guess switching to Resumable upload as upload method may help. But it's pretty much undocumented.
Looking into source code, I guess using different Send() overload may be the way forward, but I can't figure out how to use it properly.
So, instead of attaching the files into message and calling it like this:
var gmailResult = gmail.Users.Messages.Send(new Message
{
Raw = base64UrlEncodedMessage
}, "me").Execute();
I should not attach the files to message and do something like following?
var gmailResult = gmail.Users.Messages.Send(new Message
{
Raw = base64UrlEncodedMessage
}, "me", fileStream, contentType).Upload();
The second version does not return any API error, but does nothing. I'm obviously missing something here.
How do I attach more than one attachment?
This is kind of an old question, but putting an answer here just in case anyone else needs it:
I was able to achieve this by converting my mime message into a stream (attachment(s) included), and then calling this overload on Send:
UsersResource.MessagesResource.SendMediaUpload googleSendRequest = service.Users.Messages.Send(null, "youremail#gmail.com", mimeMessageStream, "message/rfc822");
IUploadProgress created = googleSendRequest.Upload();
This will upload all of the attachments with the email message content and then send it off. I was able to send two 5 megabyte attachments in an email. Previously I was not able to send even one of those via the other Send method that takes in a base64 encoded mime message.
I downloaded the red5-recorder (http://www.red5-recorder.com/) , which fails to allow me to start recording. After debugging I found that the netconnection, needed to record to a media server, created does not fire a NetStatusEvent event, so essentially it fails silently. I have implemented the connection with the following minimal working example:
trace("make net connection");
nc = new NetConnection();
nc.client = { onBWDone: function():void{ trace("bandwidth check done.") } };
trace("add event listener");
nc.addEventListener(NetStatusEvent.NET_STATUS, function(event:NetStatusEvent) {
trace("handle");
});
trace("connect!");
nc.connect("rtmp://localshost/oflaDemo/test/");
trace("connect done");
The output of this piece of code is:
make net connection
add event listener
connect!
connect done
The actionscript api states that the connect-call always fires such an event:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetConnection.html#includeExamplesSummary
Moreover, the netconnection is not 'connected' (a state of the NetConnection object) 10 seconds after the call. I also took a look at this: NetConnect fails silently in Flash when called from SilverLight But the fix suggested by the author, swapping rtmp and http in the connection uri, do not work. Also, I tested the uri and in fact the exact same code sniplet in a personal project, where it did work. I just can not seem to find why connecting to a media server fails silently in the red5-recorder project.
The awkward part is that if I pass some random string as a conenction uri, still nothing happens (no event, no exception, no crash). Also not setting nc.client becore nc.connect(), which caused exceptions in my experience, did not cause exceptions.
Any suggestions are welcome.
You are setting the address to localshost instead localhost.
nc.connect("rtmp://localshost/oflaDemo/test/");
Correct address:
nc.connect("rtmp://localhost/oflaDemo/test/");
I'm looking for a way through AJAX (not via a JS framework!) to real time monitor a file for changes. If changes where made to that file, I need it to give an alert message. I'm a total AJAX noob, so please be gentle. ;-)
Edit: let me explain the purpose a bit more in detail. I'm using a chat script I've written in PHP for a webhop, and what I want is from an admin module monitor the chat requests. The chats are stored in text files, and if someone starts a chat session a new file is created. If that's the case, in the admin module I want to see that in real time.
Makes sense?
To monitor a file for changes with AJAX you could do something like this.
var previous = "";
setInterval(function() {
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (ajax.readyState == 4) {
if (ajax.responseText != previous) {
alert("file changed!");
previous = ajax.responseText;
}
}
};
ajax.open("POST", "foo.txt", true); //Use POST to avoid caching
ajax.send();
}, 1000);
I just tested it, and it works pretty well, but I still maintain that AJAX is not the way to go here. Comparing file contents will be slow for big files. Also, you mentionned no framework, but you should use one for AJAX, just to handle the cross-browser inconsistencies.
AJAX is just a javascript, so from its definition you do not have any tool to get access to file unless other service calls an js/AJAX to notify about the change.
I've done that from scratch recently.
I don't know how much of a noob you are with PHP (it's the only server script language I know), but I'll try to be as brief as possible, feel free to ask any doubt.
I'm using long polling, which consists in this (
Create a PHP script that checks the content of the file periodically and only responds when it sees any change (it could include a description of the change in the response)
Create your XHR object
Include your notification code as a callback function (it can use the description)
Make the request
The PHP script will start checking the file, but won't reply until there is a change
When it responds, the callback will be called and your notification code will launch
If you don't care about the content of the file, only that it has been changed, you can check the last-modified time instead of the content in the PHP script.
EDIT: from some comment I see there's something to monitor file changes called FAM, that seems to be the way to go for the PHP script