guacd chapter 15

6
Chapter 15. guacamolecommonjs The Guacamole project provides a JavaScript API for interfacing with other components that conform to the design of Guacamole, such as projects using libguac or guacamolecommon. This API is called guacamole commonjs. guacamolecommonjs provides a JavaScript implementation of a Guacamole client, as well as tunneling mechanisms for getting protocol data out of JavaScript and into guacd or the server side of a web application. For convenience, it also provides mouse and keyboard abstraction objects that translate JavaScript mouse, touch, and keyboard events into consistent data that Guacamole can more easily digest. The extendable on screen keyboard that was developed for the Guacamole web application is also included. Guacamole client The main benefit to using the JavaScript API is the full Guacamole client implementation, which implements all Guacamole instructions, and makes use of the tunnel implementations provided by both the JavaScript and Java APIs. Using the Guacamole client is straightforward. The client, like all other objects within the JavaScript API, is within the Guacamole namespace. It is instantiated given an existing, unconnected tunnel: var client = new Guacamole.Client(tunnel); Once you have the client, it won't immediately appear within the DOM. You need to add its display element manually: document.body.appendChild(client.getDisplay().getElement()); At this point, the client will be visible, rendering all updates as soon as they are received through the tunnel. client.connect(); It is possible to pass arbitrary data to the tunnel during connection which can be used for authentication or for choosing a particular connection. When the connect() function of the Guacamole client is called, it in turn calls the connect() function of the tunnel originally given to the client, establishing a connection. Important When creating the Guacamole.Client, the tunnel used must not already be connected. The Guacamole.Client will call the connect() function for you when its own connect() function is invoked. If the tunnel is already connected when it is given to the Guacamole.Client, connection may not work at all. In general, all instructions available within the Guacamole protocol are automatically handled by the Guacamole client, including instructions related to audio and video. The only instructions which you must handle yourself are "name" (used to name the connection), "clipboard" (used to update clipboard data on the client side), and "error" (used when something goes wrong serverside). Each of these instructions has a corresponding event handler; you need only supply functions to handle these events. If any of these event

Upload: huynhtran

Post on 13-Sep-2015

216 views

Category:

Documents


0 download

DESCRIPTION

free

TRANSCRIPT

  • 12/6/2015 Chapter15.guacamolecommonjs

    http://guacdev.org/doc/gug/guacamolecommonjs.html 1/6

    Chapter15.guacamolecommonjsTheGuacamoleprojectprovidesaJavaScriptAPIforinterfacingwithothercomponentsthatconformtothedesignofGuacamole,suchasprojectsusinglibguacorguacamolecommon.ThisAPIiscalledguacamolecommonjs.

    guacamolecommonjs provides a JavaScript implementation of a Guacamole client, as well as tunnelingmechanismsforgettingprotocoldataoutofJavaScriptandintoguacdortheserversideofawebapplication.

    Forconvenience,italsoprovidesmouseandkeyboardabstractionobjectsthattranslateJavaScriptmouse,touch,andkeyboardeventsintoconsistentdatathatGuacamolecanmoreeasilydigest.TheextendableonscreenkeyboardthatwasdevelopedfortheGuacamolewebapplicationisalsoincluded.

    GuacamoleclientThemainbenefittousingtheJavaScriptAPIisthefullGuacamoleclientimplementation,whichimplementsallGuacamole instructions,andmakesuseof the tunnel implementationsprovidedbyboth theJavaScriptandJavaAPIs.

    UsingtheGuacamoleclient isstraightforward.Theclient, likeallotherobjectswithin theJavaScriptAPI, iswithintheGuacamolenamespace.Itisinstantiatedgivenanexisting,unconnectedtunnel:

    varclient=newGuacamole.Client(tunnel);

    Onceyouhavetheclient,itwon'timmediatelyappearwithintheDOM.Youneedtoadditsdisplayelementmanually:

    document.body.appendChild(client.getDisplay().getElement());

    Atthispoint,theclientwillbevisible,renderingallupdatesassoonastheyarereceivedthroughthetunnel.

    client.connect();

    Itispossibletopassarbitrarydatatothetunnelduringconnectionwhichcanbeusedforauthenticationorforchoosingaparticularconnection.Whentheconnect()functionof theGuacamoleclient iscalled, it in turncallstheconnect()functionofthetunneloriginallygiventotheclient,establishingaconnection.

    Important

    Whencreating theGuacamole.Client, the tunnelusedmustnotalreadybeconnected.TheGuacamole.Clientwillcalltheconnect()functionforyouwhenitsownconnect()functionisinvoked. If the tunnel is already connected when it is given to the Guacamole.Client,connectionmaynotworkatall.

    In general, all instructions available within the Guacamole protocol are automatically handled by theGuacamole client, including instructions related to audio and video. The only instructionswhich youmusthandleyourselfare"name"(usedtonametheconnection),"clipboard"(usedtoupdateclipboarddataontheclient side), and "error" (usedwhen something goeswrong serverside). Each of these instructions has acorrespondingeventhandleryouneedonlysupply functions tohandle theseevents. Ifanyof theseevent

  • 12/6/2015 Chapter15.guacamolecommonjs

    http://guacdev.org/doc/gug/guacamolecommonjs.html 2/6

    handlersareleftunset,thecorrespondinginstructionsaresimplyignored.

    HTTPtunnelBoth the Java and JavaScript API implement corresponding ends of an HTTP tunnel, based onXMLHttpRequest.

    Thetunnelisatruestreamthereisnopolling.AninitialrequestismadefromtheJavaScriptside,andthisrequestishandledontheJavaside.Whilethisrequestisopen,dataisstreamedalongtheconnection,andinstructionswithinthisstreamarehandledassoonastheyarereceivedbytheclient.

    While data is being streamed along this existing connection, a second connection attempt ismade. Datacontinues to be streamed along the original connection until the server receives and handles the secondrequest,atwhichpointtheoriginalconnectionclosesandthestreamistransferredtothenewconnection.

    This process repeats, alternating between active streams, thus creating an unbroken sequence ofinstructions,whilealsoallowingJavaScripttofreeanymemoryusedbythepreviouslyactiveconnection.

    ThetunneliscreatedbysupplyingtherelativeURLtotheserversidetunnelservlet:

    vartunnel=newGuacamole.Tunnel("tunnel");

    Oncecreated,thetunnelcanbepassedtoaGuacamole.ClientforuseinaGuacamoleconnection.

    The tunnel actually takes care of the Guacamole protocol parsing on behalf of the client, triggering"oninstruction"eventsforeveryinstructionreceived,splittingeachelementintoelementsofanarraysothattheclientdoesn'thaveto.

    InputabstractionBrowserscanbe rather finickywhen it comes tokeyboardandmouse input,not tomention touchevents.Thereislittleagreementonwhichkeyboardeventsgetfiredwhen,andwhatdetailabouttheeventismadeavailabletoJavaScript.Touchandmouseeventscanalsocauseconfusion,asmostbrowserswillgenerateboth events when the user touches the screen (for compatibility with JavaScript code that only handlesmouseevents),makingitmoredifficultforapplicationstosupportbothmouseandtouchindependently.

    TheGuacamoleJavaScriptAPIabstractsmouse,keyboard,andtouch interaction,providingseveralhelperobjectswhichactasanabstractinterfacebetweenyouandthebrowserevents.

    Mouse

    Mouse event abstraction is provided by the Guacamole.Mouse object. Given an arbitrary DOM element,Guacamole.Mouse triggers onmousedown, onmousemove, and onmouseup events which are consistentacrossbrowsers.Thisobjectonlyresponse.totruemouseevents.Mouseeventswhichareactuallytheresultoftoucheventsareignored.

    varelement=document.getElementById("somearbitraryid");varmouse=newGuacamole.Mouse(element);

    mouse.onmousedown=mouse.onmousemove=mouse.onmouseup=function(state){

    //Dosomethingwiththemousestatereceived...

    };

    ThehandlesofeacheventaregivenaninstanceofGuacamole.Mouse.Statewhichrepresentsthecurrentstateof themouse,containing thestateofeachbutton (including thescrollwheel)aswellas theXandY

  • 12/6/2015 Chapter15.guacamolecommonjs

    http://guacdev.org/doc/gug/guacamolecommonjs.html 3/6

    coordinatesofthepointerinpixels.

    Touch

    Touch event abstraction is provided by either Guacamole.Touchpad (emulates a touchpad to generateartificial mouse events) or Guacamole.Touchscreen (emulates a touchscreen, again generating artificialmouseevents).Guacamoleusesthetouchpademulation,asthisprovidesthemostflexibilityandmouselikefeatures,includingscrollwheelandclickingwithdifferentbuttons,butyourpreferencesmaydiffer.

    varelement=document.getElementById("somearbitraryid");vartouch=newGuacamole.Touchpad(element);//orGuacamole.Touchscreen

    touch.onmousedown=touch.onmousemove=touch.onmouseup=function(state){

    //Dosomethingwiththemousestatereceived...

    };

    Note that even though these objects are touchspecific, they still providemouse events. The state objectgiventotheeventhandlersofeacheventisstillaninstanceofGuacamole.Mouse.State.

    Ultimately, you could assign the same event handler to all the events of both an instance ofGuacamole.MouseaswellasGuacamole.TouchscreenorGuacamole.Touchpad,andyouwouldmagicallygain mouse and touch support. This support, being driven by the needs of remote desktop, is naturallygeared around themouse and providing a reasonablemeans of interactingwith it. For an actualmouse,eventsaretranslatedsimplyandliterally,whiletoucheventsgothroughadditionalemulationandheuristics.Fromtheperspectiveoftheuserandthecode,thisisalltransparent.

    Keyboard

    Keyboard events in Guacamole are abstracted with the Guacamole.Keyboard object as only keyup andkeydownevents there isnokeypress like there is inJavaScript.Further,all thecrazinessofkeycodesvs.scancodesvs.keyidentifiersnormallypresentacrossbrowsersisabstractedaway.AllyoureventhandlerswillseeisanX11keysym,whichrepresenteverykeyunambiguously.Conveniently,X11keysymsarealsowhattheGuacamoleprotocolrequires,soifyouwanttouseGuacamole.KeyboardtodrivekeyeventssentovertheGuacamoleprotocol,everythingcanbeconnecteddirectly.

    Just like the other input abstraction objects, Guacamole.Keyboard requires a DOM element as an eventtarget.Onlykeyeventsdirectedatthiselementwillbehandled.

    varkeyboard=newGuacamole.Keyboard(document);

    keyboard.onkeydown=function(keysym){//Dosomething...};

    keyboard.onkeyup=function(keysym){//Dosomething...};

    In this case,we are usingdocument as the event target, thus receiving all key eventswhile the browserwindow(ortab)hasfocus.

    OnscreenkeyboardThe Guacamole JavaScript API also provides an extendable onscreen keyboard,

  • 12/6/2015 Chapter15.guacamolecommonjs

    http://guacdev.org/doc/gug/guacamolecommonjs.html 4/6

    Guacamole.OnScreenKeyboard,whichrequirestheURLofanXMLfiledescribingthekeyboardlayout.Theonscreen keyboard object provides no hardcoded layout information the keyboard layout is describedentirelywithintheXMLlayoutfile.

    Keyboardlayouts

    The keyboard layout XML included in the Guacamole web application would be a good place to startregardinghowtheselayoutfilesarewritten,butingeneral,thekeyboardissimplyasetofrowsorcolumns,denotedwithandtagsrespectively,whereeachcanbenestedwithintheotherasdesired.

    Eachkey is representedwitha tag,but this isnotwhat theusersees,norwhatgenerates thekeyevent.Eachkeycontainsanynumberoftags,which represent the visiblepart of the key.ThecapdescribeswhichX11keysymwill besentwhen thekey ispressed.Each cap canbeassociatedwithanycombinationofarbitrarymodifierflagswhichdictatewhenthatcapisactive.

    Forexample:

    ShiftaA

    Herewe have a very simple keyboardwhich defines only two keys: "shift" (amodifier) and the letter "a".When"shift"ispressed,itsetsthe"shift"modifier,affectingotherkeysinthekeyboard.The"a"keyhastwocaps:onelowercase(thedefault)andoneuppercase(whichrequirestheshiftmodifiertobeactive).

    Noticethattheshiftkeyneededthekeysymexplicitlyspecified,whilethe"a"keydidnot.Thisisbecausetheonscreen keyboard will automatically derive the correct keysym from the text of the key cap if the textcontainsonlyasinglecharacter.

    Displayingthekeyboard

    Onceyouhaveakeyboardlayoutavailable,addinganonscreenkeyboardtoyourapplicationissimple:

    //Addkeyboardtobodyvarkeyboard=newGuacamole.OnScreenKeyboard("path/to/layout.xml");document.body.appendChild(keyboard.getElement());

    //Setsizeofkeyboardto100pixelskeyboard.resize(100);

    Here,wehaveexplicitlyspecifiedthewidthofthekeyboardas100pixels.Normally,youwoulddeterminethisbyinspectingthewidthofthecontainingcomponent,orbydecidingonareasonablewidthbeforehand.Oncethewidthisgiven,theheightofthekeyboardisdeterminedbasedonthearrangementofeachrow.

    Stylingthekeyboard

    While theGuacamole.OnScreenKeyboard objectwill handlemost of the layout, youwill still need to styleeverything yourself with CSS to get the elements to render properly and the keys to change state whenclicked or activated. It defines several CSS classes, which you will need to manually style to get thingslookingasdesired:

  • 12/6/2015 Chapter15.guacamolecommonjs

    http://guacdev.org/doc/gug/guacamolecommonjs.html 5/6

    guackeyboard

    This class is assigned to the root element containing the entire keyboard, returned bygetElement(),

    guackeyboardrow

    Assignedtothedivelementswhichcontaineachrow.

    guackeyboardcolumn

    Assignedtothedivelementswhichcontaineachcolumn.

    guackeyboardgap

    Assignedtoanydivelementscreatedasaresultoftagsinthekeyboardlayout.tagsareintendedtobehaveaskeyswithnovisiblestylingorcaps.

    guackeyboardkeycontainer

    Assigned to the div element which contains a key, and provides that key with its requireddimensions.ItisthiselementthatwillbescaledrelativetothesizespecifiedinthelayoutXMLandthesizegiventotheresize()function.

    guackeyboardkey

    Assigned to thediv elementwhich represents the actual key, not the cap. This elementwill notdirectlycontaintext,butitwillcontainallcapsthatthiskeycanhave.WithcleverCSSrules,youcantakeadvantageofthisandcauseinactivecapstoappearonthekey inacorner(forexample), orhidethementirely.

    guackeyboardcap

    Assignedtothedivelementrepresentingakeycap.Eachcapisachildof itscorresponding key,anditisuptotheauthoroftheCSSrulestohideorshoworrepositioneachcapappropriately.EachcapwillcontainthedisplaytextdefinedwithintheelementinthelayoutXML.

    guackeyboardrequires MODIFIER

    Addedtothecapelementwhenthatcaprequiresaspecificmodifier.

    guackeyboarduses MODIFIER

    Addedtothekeyelementwhenanycapcontainedwithinitrequiresaspecificmodifier.

    guackeyboardmodifier MODIFIER

    Added to and removed from the root keyboard element when a modifier key is activated ordeactivatedrespectively.

    guackeyboardpressed

    Addedtoandremovedfromanykeyelementasitispressedandreleasedrespectively.

    Important

    TheCSSrulesrequiredfortheonscreenkeyboardtoworkasexpectedcanbequitecomplex.LookingovertheCSSrulesusedbytheonscreenkeyboardintheGuacamolewebapplicationwouldbeagoodplacetostarttoseehowtheappearanceofeachkeycanbedriventhroughthesimpleclasschangesdescribedabove.

    InspectingtheelementsofanactiveonscreenkeyboardwithintheGuacamolewebapplicationwiththedevelopertoolsofyourfavoritebrowserisalsoagoodidea.

  • 12/6/2015 Chapter15.guacamolecommonjs

    http://guacdev.org/doc/gug/guacamolecommonjs.html 6/6

    Handlingkeyevents

    KeyeventsgeneratedbytheonscreenkeyboardareidenticaltothoseofGuacamole.KeyboardinthattheyconsistonlyofasingleX11keysym.Onlykeyupandkeydowneventsexist,asbeforethereisnokeypressevent.

    //AssumingwehaveaninstanceofGuacamole.OnScreenKeyboardalready//called"keyboard"

    keyboard.onkeydown=function(keysym){//Dosomething...};

    keyboard.onkeyup=function(keysym){//Dosomething...};