# Presentation: 173885

## Developing Shared Applications

- Susanne Lefvert
- lefvert@mcs.anl.gov
- University of Chicago

## Outline

- Overview
- Sharing State
- Event Communication
- SharedAppClient
- DatastoreClient
- Packaging and Installation
- Example: Shared PDF
- Exercises
- Documentation

## Shared Applications

- Allows individuals to use programs
- together from remote locations

- Shared Browser
- Browse the web together
- Shared Presentation
- View and control remote presentations
- Shared VNC
- Secured screen sharing
- Question and Answer Tool
- Remotely post questions and answers

## Shared Applications

## Sharing State

- Venue

**foo**

**foo**

**foo**

**Client 1**

**Client 2**

**Client 3**

*** Communicating via SOAP calls**

**Application Session**
**State:**

**foo**

## Event Communication

**bar**

**foo**

**foo**

**bar**

**bar**

**Client 1**

**Client 2**

**Client 3**

*** Communicating via GSITCP Sockets**

- Venue

**Event** **Channel**

**Application Session **

**Event** **Channel**

## SharedAppClient

**Your Application**

**SharedAppClient**

**SharedApplicationIW**

**Application Session **

**Event** **Channel**

**EventClient**

## SharedAppClient

- _[http://www.mcs.anl.gov/fl/research/accessgrid/documentation/developer/api/](http://www.mcs.anl.gov/fl/research/accessgrid/documentation/developer/api/)_

- Tool for developers
- Hides details about
- SOAP communication
- Event communication
- Logging
- Data cache
- Exception handling
- API
- AccessGrid.SharedAppClient
- AccessGrid.SharedApplication.SharedApplicationIW

## SharedAppClient

- _API:_
***Join()*** – Connect to an application session
***InitLogging()*** – Get object for logging
***Shutdown()*** – Shut down soap interface and event client
***SendEvent()*** – Distribute an event to all clients
***RegisterEventCallback()*** – Register callback for event
***SetData()*** – Set shared state
***GetData()*** – Get shared state
***UpdateDataCache()*** – Update cached data
***GetPublicId()*** – Get my unique id
***GetVenueURL()*** – Get venue url

## DatastoreClient

- _API:_
***LoadData()*** – Get data from venue
***QueryMatchingFiles()*** – Get file names matching pattern
***GetFileData()*** – Get data description for a file
***Download()*** – Download file from venue
***Upload()*** – Upload file to venue
***RemoveFile()*** – Remove file from venue

## Create an application description file.
SharedMyApp.app 
Create an Access Grid package.
SharedAppName.agpkg 
Use agpm.py to install the application.
agpm.py --help
Open the package in the Venue Client 
Start application sessions in the Venue Client.

- SharedMyApp.app
- Create an Access Grid package.
- SharedAppName.agpkg
- Use agpm.py to install the application.
- agpm.py --help
- Open the package in the Venue Client
- Start application sessions in the Venue Client.

- Packaging and Installation

- [application]
- name = SharedMyApp
- mimetype = application/x-ag-shared-myapp
- extension = sharedmyapp
- files = SharedMyApp.py, otherFile
- [commands]
- Open = %(python)s SharedMyApp.py -a %(appUrl)s

## Example: Shared PDF

## Example: Shared PDFSharedAppClient

-  # Create shared application client
-  self.sharedAppClient = SharedAppClient(name)
-  self.log = self.sharedAppClient.InitLogging()
-  # Get client profile
-  clientProfile = ClientProfile(UserConfig.instance().GetProfile())
-  # Join the application session
-  self.sharedAppClient.Join(appUrl, clientProfile)
-  self.id = self.sharedAppClient.GetPublicId()
-  # Register callbacks for external events
-  self.sharedAppClient.RegisterEventCallback("openFile", self.OpenCallback)
-  self.sharedAppClient.RegisterEventCallback(“changePage",                                                                           self.ChangePageCallback)

## Example: Shared PDFGet Current State

- _State_: URL to file and current page number

- # Get current state
- self.file = self.sharedAppClient.GetData(“file")
- self.pageNr = self.sharedAppClient.GetData(“page")
- if self.file:
-     try:
-         self.dataStoreClient.Download(self.file, "tmp")
-         self.pdf.LoadFile("tmp")
-         self.pdf.setCurrentPage(self.pageNr)
-     except:
-         self.log.exception("PdfViewer.__init__: Download
- 				 failed %s"%(self.file))

## Example: Shared PDF

## Example: Shared PDFEvent Communication

- # -- sender ---
- def OnNextPageButton(self, event):
-         '''Invoked when user clicks the next button.'''
-         self.pageNr = self.pageNr + 1
-         self.pdf.setCurrentPage(self.pageNr)
-         self.sharedAppClient.SendEvent(“changePage", (self.id, self.pageNr))
-         self.sharedAppClient.SetData("page", self.pageNr)
- # --- receiver ---
- def ChangePageCallback(self, event):
-         ''' Invoked when a changePage event is received.'''
-         id, self.pageNr = event.data
-         # Ignore my own events
-         if self.id != id:
-             wxCallAfter(self.pdf.setCurrentPage, self.pageNr)

- _Event_:  type – “changePage”, data – unique ID and page number

## Example: Shared PDF

## Example: Shared PDFDatastoreClient

-   def PopulateCombobox(self, default = None):
-         # Get pdf files from venue
-         fileNames = []
-         wxBeginBusyCursor()
-         try:
-             self.dataStoreClient.LoadData()
-             fileNames = self.dataStoreClient.QueryMatchingFiles("*.pdf")
-         except:
-             self.log.exception("FileSelectorDialog.PopulateCombobox: Failed.")
-         wxEndBusyCursor()
-         # Update combobox
-         self.pdfList.Clear()
-         for file in fileNames:
-             self.pdfList.Append(file)

## Example: Shared PDFPackaging and Installation

- 1. Create SharedPDF.app:
- 2. SharedPDF.py + SharedPDF.app => SharedPDF.agpkg (zip)
- 3. agpm.py --p SharedPDF.agpkg

- [application]
- name = Shared PDF
- mimetype = application/x-ag-shared-pdf
- extension = sharedpdf
- files = SharedPDF.py
- [commands]
- Open = %(python)s SharedPDF.py -v %(venueUrl)s -a %(appUrl)s

## Starting Application Session

## Exercises

**Exercise 4 – Shared Applications: **
- Shared Stoplight
- Shared Group Chat

- _[http://www.mcs.anl.gov/fl/research/accessgrid/documentation/tutorial/AGTk_2.4](http://www.mcs.anl.gov/fl/research/accessgrid/documentation/tutorial/AGTk_2.4)_

**Notes:**
The configuration exercises will focus configuring your AG environment. You will run the software from the command line with different command line options and learn how to inspect the log files. You will use both node management and the node setup wizard to create a node configuration. You will use certificate management tool. You will setup and run a server and a bridge. For those of you who have time, this session also includes instructions on how to run the toolkit from CVS and how to create a vv2d file for automatically launching the Venue Client from a web site. 

## Exercise 1: Shared Stoplight

## Exercise 1: Shared Stoplight

- Creating the application environment
- Initializing the AG environment
- Creating SharedAppClient
- Joining the application session
- Registering event callbacks
- Retrieving initial state
- Sending and receiving events
- Setting application state

## Exercise 1: Shared Stoplight

- Three Exercises:
- Create an AG package, install, and start the application from the Venue Client.
- Add a new button – yellow
- Add a text field to change the title

## Exercise 1: Shared Stoplight

## Exercise 2: Shared Group Chat

## Documentation

- Contributed Software Page
- _[http://www.mcs.anl.gov/fl/research/accessgrid/wiki/moin.cgi/ContributedSoftware](http://www.mcs.anl.gov/fl/research/accessgrid/wiki/moin.cgi/ContributedSoftware)_
- Reference Materials
- _[http://www.mcs.anl.gov/fl/research/accessgrid/wiki/moin.cgi/DevelopingSharedApplications](http://www.mcs.anl.gov/fl/research/accessgrid/wiki/moin.cgi/DevelopingSharedApplications)_
- Toolkit API
- _[http://www.mcs.anl.gov/fl/research/accessgrid/documentation/developer/api/](http://www.mcs.anl.gov/fl/research/accessgrid/documentation/developer/api/)__ _