Web

From Blue Mars Developer Guidebook

Jump to: navigation, search
There are security restrictions on this article

Contents

Overview

This page describes bringing up a web page in a browser and sending HTTP requests to a web server. See the High Score Server example.

For a convenient way to perform HTTP requests asynchronously and handle the results with callbacks, see ARWebUtils. The Web API Overview compares available functions.


Browser

The default web browser on the user's computer can be invoked to display a web page.


Game.ShowPageInBrowser(url)
brings up a web page in the default browser


Downloading

The following functions manage HTTP requests. These functions are typically used to download files for further processing but can also be used to just submit information to a web server.

HTTP and HTTPS URL's are supported (except on x64 builds SSL is currently not supported). HTTP GET requests are assumed unless POST data is supplied.

See the HTTP specification for the gory details, but this tutorial covers most of what you need to know.


ARDownloadFile(url, destfile, options)
generate an HTTP request with the specified URL, save the returned data
Note: the saved file can be read in with ARLoadXML


Only one download can be in progress at a time (unless you explicitly set up concurrent downloads). Use this function to check if a download is already in progress or confirm if a download has completed.]


Game.IsDownloading(options)
return true if a download is in progress, false otherwise

While a download is progress, you will probably want to display some kind of progress indicator.


Game.GetDownloadProgress(options)
return the download progress as a float, from 0-1

You can also stop a download while it's in progress.


Game.StopDownload(options)
stops a download

Once a download has completed, you should check that it has actually succeeded.


Game.GetDownloadError(options)
returns an error code for the most recent download


Game.GetDownloadStatusCode(options)
return the HTTP status code of the most recent download


Game.GetDownloadFileTime(options)
return the file time (number of seconds since January 1, 1970)

#concurrent_downloads involves creating multiple downloaders. Once finished, you should clean them up.


Game.RemoveDownload(file)
remove the downloader created for this destination file

External Downloader

The downloader provided by the default service ("AvatarReality") is built into the Blue Mars client. Alternatively, you can perform the downloader in an external downloader application.

Image:Mydownloader.JPG

To use the external downloader, simply specify "ARExternal" as the service parameter for each of the download functions. Although the same set of functions is used, note there is less integration with the external downloader so progress and error information is currently not returned - currently just Game/DownloadFile and Game/IsDownloading is meaningful. Progress and error information is displayed in the external downloader itself, though. Also, POST requests are not supported.

Concurrent Downloads

Each service maintains a single downloader object for everyone to use, but that downloader can only handle one download a time. If you want to invoke two or more concurrent downloads you can request that the specified (or default) service create a new downloader for you (see ARDownloadFile for details. Then you can refer to that specific downloader by supplying a destination "file" parameter to all the download functions (it should match the second parameter you specified in ARDownloadFile. When you are finished with a "new" downloader, remember to clean it up with Game.RemoveDownload, again specifying the same destination file.

Note with the external downloader, multiple downloader objects will interact with just the one external application.

Utilities

Functions for common operations are implemented in Game/Scripts/Utils/AR/ARWeb.lua. You can use these as-is or as example code.

Monitoring

This is just a debug function for printing the download progress on-screen. You will probably want something more polished, like sending the download progress to a Flash display.

-- prints download progress on screen
function ARDownloadProgress()
   ARPrint("downloading "..(100*Game.GetDownloadProgress()).."%");
end

Error Checking

This function just checks the error code of the latest download, using Game.GetDownloadError

function ARDownloadOK()
   local code = Game.GetDownloadError();
   return (code>0);
end

Sometimes it's handy to associate the error code with a printable message, so here's a function that indexes the error code into a table of error messages.

function ARDownloadErrorString(code)
   if (code<0 or code>eFDE_LastError) then
      return "Invalid error code "..code;
   else
      return ARDownloadErrors[code+1];
   end
end
ARDownloadErrors = {
   "NoError",
   "OutOfMemory",
   "BufferOverflow",
   "ParseURLFailed",
   "HostLookupFailed",
   "SocketFailed",
   "ConnectFailed",
   "BadResponse",
   "RequestRejected",
   "Unauthorized",
   "Forbidden",
   "FileNotFound",
   "ServerError",
   "FileWriteFailed",
   "FileIncomplete",
   "FileTooBig",
   "EncryptionError",
   "RequestCancelled",
   "NotModified",
   "LastError",
};

We have a similar function to return a string for an HTTP status code. It's a little bit more involved, since the status codes are segmented into separate ranges.

function ARHTTPStatusString(code)
-- Lua arrays start indexing at 1!
   local section = math.floor(code/100);
   local index=1+code%100;
   if (section<1 or section>5) then
      return "Invalid HTTP code";
   else
      return ARHTTPStatusCodes[section][index];
   end
end
ARHTTPStatusCodes = {
   -- 1xx - Informational
   { 
      "Continue",
      "Switching Protocols",
   },
   -- 2xx  Successful
   {
      "OK",
      "Created",
      "Accepted",
      "Non-Authoritative Information",
      "No Content",
      "Reset Content",
      "Partial Content",
   },
   -- 3xx Redirection
   {
      "Moved Permanently",
      "Found",
      "See Other",
      "Not Modified",
      "Used Proxy",
      "(Unused)",
      "Temporary Redirect",
   },
  -- 4xx Client Error
   {
      "Bad Request",
      "Unauthorized",
      "Payment Required",
      "Forbidden",
      "Not Found",
      "Method Not Allowed",
      "Not Acceptable",
      "Proxy Authentication Required",
      "Request Timeout",
      "Conflict",
      "Gone",
      "Length Required",
      "Precondition Failed",
      "Request Entity Too Large",
      "Request-URI Too Long",
      "Unsupported Media Type",
      "Requested Range Not Satisfiable",
      "Expectation Failed",
   },
   -- 5xx Server Error
   {
      "Not Implemented",
      "Bad Gateway",
      "Service Unavailable",
      "Gateway Timeout",
      "HTTP Version Not Supported",
   }
};

Submitting GET/POST Parameters

These functions facilitate sending parameters with HTTP GET and POST requests.

First, some functions to get parameters into the right format. This code is very similar to some example code in the Lua manual - http://www.lua.org/pil/20.3.html


ARURLEncode(s)
return value - url-encoded string
s - string parameter convert
function ARURLEncode(s)
   s = string.gsub(s, "([&=+%c])", function (c)
				      return string.format("%%%02X", string.byte(c))
				   end)
   s = string.gsub(s, " ", "+")
   return s
end


ARDownloadParamString(params)
convert a table of key/value pairs into a string for HTTP submission
return value - string parameter string
params - table table of parameters
function ARDownloadParamString(params)
   local str = "";
   for key,value in pairs(params) do
      if (str ~= "") then
	 str = str.."&"; -- separate params with &
      end
      str = str..ARURLEncode(key).."="..ARURLEncode(value);
   end
   return str;
end


ARSubmitGet(url, dest, params, options)
issue an HTTP GET request with the supplied parameters
function ARSubmitGet(url, dest, params, options)
   if not options then
      options = {};
   end
   params = ARDownloadParamString(params);
   ARDownloadFile(url.."?"..params,dest,options);
end


ARSubmitPost(url, dest, params, options)
issue an HTTP POST request with the supplied parameters
options - table optional table of HTTP parameters, same as in Game/DownloadFile
function ARSubmitPost(url, dest, params, options)
   if not options then
      options = {};
   end
   options.post=ARDownloadParamString(params);
   ARDownloadFile(url,dest,options);
end

Note that these functions are just wrappers around ARDownloadFile. You are still responsible for checking the progress and completion status.


Caching

-- download file if age is less than provided time
-- blocks
function ARDownloadIfNewer(url,file,time)
   ARDownloadFile(url,file,{trace=true});
   ARPrintReset();
   while Game.IsDownloading() do
      ARDownloadProgress();
   end
   if ARDownloadFileAge() > time then
      ARDownloadFile(url,file);
   end
end
-- download file if newer than local version
-- blocks
function ARDownloadIfNewerFile(url,file)
   local time = System.GetFileTime(file);
   ARDownloadIfNewer(url,file,time);
end

Queue

-- a simple download queue
-- roll your own if you need something more complex
--  e.g. progress display or error checking
g_ARDownloads = {}

-- queue a download task
-- same parameters as Game.DownloadFile
function ARDQSchedule(url,file,options,callback)
   local task = {url=url,file=file,options=options or {},active=false,callback=callback};
   table.insert(g_ARDownloads,task);
end

-- update the download queue
function ARDQUpdate()
   if (not ARDQEmpty()) then
      if (not Game.IsDownloading()) then
	 local download = g_ARDownloads[1];
	 if (not download.active) then
	    -- task waiting, start it
	    download.active=true;
	    ARDownloadFile(download.url,download.file,download.options);
	 else
	    -- task finished, remove from queue
	    if download.callback then download.callback() end
	    table.remove(g_ARDownloads,1);
	    ARDQUpdate();
	 end
      end
   end
end

-- test whether download queue is empty (finished)
function ARDQEmpty()
   return (# g_ARDownloads) == 0;
end

Example usage: this test state in Game/Scripts/Entities/Tests/AR/ARWeb.lua queues two downloads and updates/monitors the download queue.

ARTestWeb.DownloadQueue =
{
	OnBeginState = function(self)
			  ARDQSchedule(self.Properties.url,self.Properties.results,{});
			  ARDQSchedule(self.Properties.flashurl,self.Properties.flashresults,{});
	end,
	OnUpdate = function(self,delta)
			 ARPrintReset();
		      if (not ARDQEmpty()) then
			 ARPrint("Downloading queue of "..(# g_ARDownloads).. "files");
			 ARDownloadProgress();
			 ARDQUpdate();
		      else
			 ARPrint("Finished downloading queue");
		      end
	end,
}

Examples

Larger-scale examples that use the web functions:

Problems with this wiki page? Contact us either by: Support Email or Support Ticket System

Blue Mars Guidebook Privacy Policy
Blue Mars Guidebook Community Guidelines

Personal tools