AccessGrid.org

Shared Applications

 

The Access Grid Toolkit aims to enable rich collaboration. The Shared Application API along with the rest of the Access Grid Toolkit intends to allow developers to create collaborative applications more easily.

The core features included in the Shared Application API include:

  • Shared Application data for storing simple state data.
  • Shared Application Event service For sending information between participants.

Other resources that shared applications can utilize are a virtual venue, the venue's participants, event service, data storage, text chat, and multimedia services.

This tutorial will demonstrate how to use the different components when creating a shared application.

 

Initial Setup

Make sure you:

  • Have the Access Grid 3 Toolkit installed on your machine,
  • Are able to run the VenueClient successfully,
  • Are able to connect the VenueClient to a Venue when you click "Go".
  • Download the tutorial code.

 

Part 1 -- A basic Shared Application

The first example "Joins" a shared application and exits.

Before doing this, any application that uses the Access Grid Toolkit should first initialize the Toolkit. It's not required for everything, but it allows you to use various things such as certificates, logging, and the Access Grid configuration and information.

from AccessGrid import Toolkit
app = Toolkit.CmdlineApplication.instance()
app.Initialize("BasicApp")

The toolkit should now be initialized and errors and debugging information will now be put in a logfile: ~/.AccessGrid3/Logs/BasicApp.log

The SharedAppClient is a class that simplifies common tasks for Shared Applications. We'll create one like this:

sharedAppClient = SharedAppClient("BasicApp")
sharedAppClient.InitLogging()

Now we'll join the SharedApplication:

sharedAppClient.Join(appUrl, GetClientProfile() )

That's it!

Once we're finished with our application, we generally shutdown like this:

sharedAppClient.Shutdown()

Test this yourself by going to the part1 directory and running the BasicApp.py application. Note that you should specify which venue to use on the cmd-line like this:

python BasicApp.py <venueUrl>

The easiet place to find a venueUrl is in your VenueClient. Also, if you have a local server running, the test will try to use it if no venueUrl is specified.

 

Part 2 -- Getting General Information about a running Shared Application.

The Shared Application State shows general information about the shared application instance running on the server.

state = sharedAppClient.GetApplicationState()
print " Application State:"
print ' name:', state.name
print ' desc:', state.description
print ' id:', state.id
print ' mimeType:', state.mimeType
print ' uri:', state.uri
print ' data:', state.data

Test this by going to the part2 directory and running GetSharedAppState.py.

 

Part 3 -- Shared App Data

SharedAppData is a shared place for shared applications to store information. It's often used to hold state information for late joining participants. For example, in the shared browser, the current url is stored there so when someone who joins late, the web page that everyone else is looking at is loaded.

If large amounts of data need to be stored, see one of the later examples that describes the venue data store instead.

To set data:

testKey = "test key"
testValue = "test value"
sharedAppClient.SetData( testKey, testValue )

To get data:

value = sharedAppClient.SetData( "test key" )

To get the list of data keys that are available:

keys = sharedAppClient.GetDataKeys()
print keys

Go to the part3 directory and run SharedAppDataExample.py.

Suggested Task:

Modify the code to set different shared app keys and data.

 

Part 4 -- Shared App Events

Events allow running sharedAppClients to communicate with each other.

Our test application will send an event, but first let's register to receive the event as well.

def event1Callback():
print "- Received event."
sharedAppClient.RegisterEventCallback("event1", event1Callback )

Next we'll send the event. Here is a function to that will send a simple event:

def sendEvent():
sharedAppClient.SendEvent("event1", "somedata")

Note that Access Grid uses asynchronous networking with the help of the Twisted Toolkit. Asynchronous networking means that code won't block waiting for network calls to finish and will continue processing other code instead. We generally ask to be notified when network calls such as connect are completed. In this case we'll ask that our send function be run once the connection is made:

sharedAppClient.eventClient.RegisterMadeConnectionCallback(sendEvent)

Go to the part4 directory and run AppEvents.py

Suggested Task:

Register to receive a new event, and send and receive it.

 

Part 5 -- Venue Data Store

To access a venue's datastore, a shared application needs a venueUrl, which provides the venue's location, and a connectionId to show that the user has permission to access the venue. A connectionId is received when a connection to a venue is established, typically by a VenueClient. The connectionId and venueUrl are typically passed to the shared application (see the later packaging example).

Alternatively, the VenueClient's connectionId can be requested from a connected VenueClient on the local machine like this:

(optional)
venueClient = VenueClientIW(venueClientUrls[0])
connectionId = venueClient.GetClientProfile().connectionId

Communicating which a venue's DataStore is made easier by the DataStoreClient:

dataStoreClient = GetVenueDataStore(venueUrl, connectionId)

Following are the main operations that the DataStoreClient provides:

Querying files:

filenames = dataStoreClient.QueryMatchingFiles("*")

Downloading a file:

dataStoreClient.Download(filename, localDownloadFilename

Uploading a file:

dataStoreClient.Upload(filename)
# Reload the file list since it will be different now
dataStore.LoadData()

Deleting a file:

dataStoreClient.RemoveFile(filename)

Go to the part5 directory and run SharedAppVenueData.py

 

Part 6 -- A Shared Application with A UI

This example shows a simple shared application with a wxPython user interface.

We'll create a class based on wxApp:

class SharedAppExample(wxApp):
def __init__( self, appUrl):
wxApp.__init__(self, False)
reactor.interleave(wxCallAfter)
...
self.sharedAppClient = SharedAppClient("Shared App Example")
self.log = self.sharedAppClient.InitLogging()
self.sharedAppClient.Join(appUrl, clientProfile)
self.sharedAppClient.eventClient.RegisterMadeConnectionCallback(
self.madeConnectionCallback)

self.frame = wxFrame(None, -1, "Shared App Example")
... # wx UI creation
EVT_BUTTON(self.frame, -1, self.OnButton)
EVT_BUTTON(self.frame, self.quitButtonId, self.Quit)
...

Define methods to shutdown when the application is exited:

def Quit(self, event=None):
self.frame.Close()

def OnExit(self):
reactor.stop()

try:
self.sharedAppClient.Shutdown()
except:
traceback.print_exc()

# Allow twisted reactor to finish.
while len(self.reactorFinished) == 0:
reactor.iterate()

Now that the class is defined, let's initialize the Access Grid Toolkit. Note the different name for initializing applications based on wx:

app = Toolkit.WXGUIApplication.instance()
app.Initialize("appName")

And start the application:

wxInitAllImageHandlers()
app = SharedAppExample(appUrl)
reactor.addSystemEventTrigger('after', 'shutdown', app.ReactorFinished)
app.MainLoop()

Go to the part6 directory and run SharedAppWithUI.py

Suggested Tasks:
Add a gui button to send an event.
Add a text box to set shared app data.

 

Examples

login or register to post comments