Overview

If your training content is tightly integrated with your platform and not easy to package for third-party use, delivering self-contained SCORM or AICC files to that LMS is a tough, if not impossible task. Rustici Cross Domain (RXD) solves this problem by helping you deliver your training content to your customers in the format they require, while maintaining control of the content and overall learner experience.

RXD allows you to create proxy files (SCORM 1.2, SCORM 2004 3rd Edition and AICC packages) that your customer uploads in their LMS. From a client perspective, this package appears like any other course – the course registration and launch process are the same.

When a learner launches the proxy file in the LMS, they are directed back to your servers to access the content. Once the learner exits the course or completes another action specified by your developers, Rustici Cross Domain sends key information to the LMS including Completion, Score, Time and Pass/Fail.

Because the content assets remain on your servers, you remain in control of all course functionality, reporting and features. That means you’ll be able to save important course data (including Completion, Score, Time and Pass/Fail) and learner data (including Student Name and Student ID) for your own reporting needs as well as sending it to your customer’s LMS.

Setup and Installation

Your Rustici Cross Domain deliverable contains two folders:

To complete a successful RXD integration, you will need to include the RXD JavaScript files and relevant API calls in your content and create a SCORM/AICC package for the host LMS corresponding to each individual course.

Testing the Sample Content

The sample files (located in the remotecontent folder) are available for testing and debugging your setup.

It's a good idea to test the sample in order to confirm that remotely hosted content can communicate with a target LMS. If your target LMS (or LMSs) are not yet available for testing, you can easily use Rustici Software's hosted Cloud product for testing by setting up a trial account.

To set up a test of the sample content:

  1. Place the files from server in a shared location on the remote server to be used by your courses. We recommend that your content server serve files over https rather than http.
  2. Open the client folder and choose a learning standard template folder. Open the sdxd/configuration.js.template file and save it as configuration.js. Update the values, replacing the remote host parameters with your remote content server hostname and path to the remote content.
  3. Update the imsmanifest.xml (for SCORM) or the .crs and .des files (for AICC) to replace the {COURSE_TITLE} values with your information.
  4. Select all the files in the template folder, and package them as a ZIP archive. Note: your zip should have these files at its root, not in a subfolder.
  5. Import the zip package into your target LMS, and then launch it.

If the launch works, you should be able to see a rendered version of /server/remotecontent/contentsample.html, which includes buttons that test the RXD API calls. After clicking "Commit Data" and "ConcedeControl", any other API calls you made should be communicated to the host LMS.

Configuring the Remote Content

Now that you have a proof of concept of remotely hosted content using the RXD API to send SCORM/AICC API data to a host LMS, it's time to make that content your own.

There are a few basic steps to this:

  1. Create a generic landing page to redirect learners to the proper content. This page should include the RXD scripts for all content to share via an iframe or frameset.
  2. Add your content.
  3. Include the RXD JavaScript file.
  4. Integrate the RXD API.

As we mentioned above, it's generally a good idea to ensure that your content is served over the same scheme as your target LMS (i.e., either http or https), probably preferring https as a default. If there is a scheme mismatch, you can wind up invoking browser security warnings.

The Landing Page

It is our expectation that many customers will use a single gateway page in front of a variety of dynamic pieces of content.

For instance, you might have Package1.zip and Package2.zip, each of which point to this gateway page to pull in different bits of remote content from your content server.

A common implementation approach is to read the values passed in on the query string to send the user to the proper place based on (content) server-side logic.

As an example of how to pass custom data to your content, the parameters clientid and courseid are supplied as examples via CustomParams in the configuration.js template file. They are both optional and passed to the ContentURL as a params querystring value for you to parse accordingly. clientid is included to represent a package representing a given learner or LMS. courseid is intended to represent an ID for a course that will be included dynamically by the content server. You can remove these parameters, change them, add to them ... whatever you need to do to pass parameters on a per-package basis to the content server. But do note that they are fixed per package.

In your landing page (whatever you call it), the important part is that you preserve any querystring or hash values when you ultimately redirect to the actual content. Without those values, the RXD server-side script will not be able to function properly.

Add Your Content

We provide remotecontent/contentsample.html, again, as a sample. You probably shouldn't use a file called contentsample.html to build your production content, and you don't need for the content you do use to live in a folder called "remotecontent". All you really need to do is ensure that whatever content you provide is available to the landing page for redirection.

Include the RXD JavaScript

In remotecontent/contentsample.html, you will notice this line in the head element:

<script language="javascript" src="../sdxd/sdxd.server.min.js"></script>

This is content that has included the RXD JavaScript to enable use of the RXD API.

One of the most important concepts of RXD is a read-once design. I.e., after the host LMS package has read a few key bits of information and passed them to the content server, the remotely hosted content never accepts additional messages.

What this means for your content is that you probably want to pursue one of two approaches:

Integrate the RXD API

With the JavaScript correctly included, you can now start using the RXD API.

The RXD API is a subset of the Rustici Driver API.

In short, you get completion, satisfaction (pass/fail), score, location, suspend data, and the ability to record interaction details (question/answer).

For best LMS response, you generally want to call CommitData whenever you make a set call of any kind on a page.

The Kickoff Meeting

Thank you for purchasing Rustici Cross Domain (or RXD for short). We like to start each new RXD project with a "kickoff" meeting of all involved parties. This meeting is an opportunity for the technical team at your organization and our team at Rustici Software to introduce themselves to one another, for our team to learn about the goals and timeframe for the project, and for your team to learn some of the technical details of RXD. A typical agenda for an RXD kickoff meeting is as follows:

  1. Introduce the members of each team, and briefly describe their roles in this project.

  2. Describe your use case for RXD; what problem does it solve in your application?

  3. A technical tour of the RXD deliverable, with attention to the places where your team will need to make modifications. There are two folders in the deliverable:

    a. The client folder, which contains templates for SCORM 1.2, SCORM 2004, and AICC packages that can be imported and launched by a conformant LMS. Special attention is given to the manifest files (imsmanifest.xml for SCORM, course.crs and course.des for AICC) and configuration.js, which need to be edited to create usable RXD client packages.

    b. The server folder, which contains the JavaScript and HTML files that should be placed on your server, where they will be accessible by your content. It also contains a contentsample.html page that demonstrates the RXD API.

  4. An overview of the functions available in the RXD API.

  5. A live demonstration of the RXD example content.

  6. Time for your team to ask any questions they have about RXD or the project.

Rustici Cross Domain API

Rustici Cross Domain supports the following subset of the Rustici Driver API.

Start / Finish Functions

SetReachedEnd()

You can optionally call this function to indicate that the user has made sufficient progress in the content to be considered complete. This function is useful for content that has a final diploma or confirmation page. When that final page is reached, you should call SetReachedEnd, that way if the user closes the browser before initiating an action that calls Finish, the LMS will be told that the user completed the content instead of unloading the content.

ConcedeControl()

This function will pass control back to the LMS. Note, this function call should originate from a child (or descendent) frame of the indexapi.html page. It should not be invoked from a popped up window.

Utilities

CommitData()

This function will tell the LMS that you want to ensure all of the data you have sent to it is immediately persisted. Some LMS’s will cache data for a while before saving it permanently, invoking this function ensures that any cached data is permanently saved. It is best to call this function on each page where you set values. This flushes the previously set values to the LMS.

Storing and Retrieving General Data

NOTE: All values set with RXD are held locally in the JavaScript object and they are set on launch with values from the LMS. Getting a value using the below methods gets the locally stored value and not neccesarily the value currently on the LMS. Calling CommitData after setting values will send those values to the LMS and also updates the locally held data.

GetStudentID()

Returns the ID of the student currently taking the content. There is no technical reason why you should need this value unless your content is performing some functionality that is outside the scope of the standards or unless the content displays the student’s ID.

GetStudentName()

Returns the name of the student currently taking the content. Formatted “Last Name, First Name”

GetBookmark()

This function returns the last value that was saved using SetBookmark. If SetBookmark was not called previously, this function returns an empty string. This function is useful to call at the beginning of the content to retrieve the user’s last location and give him/her the option to return to that location.

SetBookmark(val)

Saves a string that represents the user’s current location in the content. This string can be formatted however you choose as long as it is less than 255 ASCII characters. This function should be called periodically as the user progresses through the content.

GetSuspendData()

This function returns the last value that was saved to the suspend data bucket. If SetSuspendData was not called previously, or there was no suspend data available on launch, this function returns an empty string.

SetSuspendData(val)

This function allows you to save a string of data up to 4000 characters. This data can represent anything; it is just an arbitrary chunk of data. This function is useful for saving internal state data that does not correspond to any other data element.

Testing

GetScore()

Retrieves a score (float) previously recorded by SetScore. If no score was previously set, this function returns an empty string.

SetScore(score, max, min)

Allows you to record the score that the user achieved in the content to the LMS. In addition, you should also specify the minimum and maximum scores that were available. All scores should be numbers (float) between 0 and 100.

State Functions

GetStatus()

Returns the current lesson status of the content. Possible values are:

SetPassed()

Sets the current status of the content to passed. If there is a mastery score stored in the LMS (as specified in your content packaging) and if you record a score for the content, then this function does not need to be called; the LMS will automatically compare the score to the mastery score to determine if the content was passed or failed.

SetFailed()

Sets the current status of the content to failed. If there is a mastery score stored in the LMS (as specified in your content packaging) and if you record a score for the content, then this function does not need to be called; the LMS will automatically compare the score to the mastery score to determine if the content was passed or failed.

ResetStatus()

Resets the status of the content back to incomplete if you previously set it to passed or failed.