package Ġcom . ra um f eld . w amp . session Ċ Ċ import Ġcom . ra um f eld . w amp . Id Generator Ċ import Ġcom . ra um f eld . w amp . protocol .* Ċ import Ġcom . ra um f eld . w amp . pubsub . Publication Event Ċ import Ġcom . ra um f eld . w amp . pubsub . Subscription Event Ċ import Ġcom . ra um f eld . w amp . rpc . Cal lee Event Ċ import Ġcom . ra um f eld . w amp . rpc . Caller Event Ċ import Ġcom . ra um f eld . w amp . session . W amp Session . State .* Ċ import Ġcom . ra um f eld . w amp . session . W amp Session . Trigger .* Ċ import Ġcom . ra um f eld . w amp . websocket . WebSocket Close Codes Ċ import Ġcom . ra um f eld . w amp . websocket . WebSocket Delegate Ċ import Ġkotlinx . coroutines . Coroutine Start Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . channels . Receive Channel Ċ import Ġkotlinx . coroutines . channels . Send Channel Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . sync . Mutex Ċ import Ġkotlinx . coroutines . sync . with Lock Ċ import Ġkotlinx . serialization . json .* Ċ Ċ /** Ċ Ġ* ĠThe ĠW AMP Ġsession Ġabstraction . ĠClients Ġneed Ġto Ġprovide Ġa Ġ[ WebSocket Delegate ] Ġso Ġwe Ġcan Ġoperate Ġon ĠWebSocket s Ġon Ġmultiple Ġplatforms . Ċ Ġ* ĠThe Ġgiven Ġ[ W amp Session Listener ] Ġis Ġnotified Ġwhen Ġimportant Ġlifecycle Ġevents Ġoccur . Ċ Ġ*/ Ċ class ĠW amp Session ( ĊĠĠĠ Ġprivate Ġval Ġweb Socket Delegate : ĠWebSocket Delegate , ĊĠĠĠ Ġprivate Ġval Ġsession Listener : ĠW amp Session Listener ? Ġ= Ġnull , ĊĠĠĠ Ġprivate Ġval Ġid Generator : ĠId Generator Ġ= ĠId Generator () Ċ ) Ġ{ ĊĊĠĠĠ Ġinterface ĠW amp Session Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠJoin ing Ġthe Ġspecified Ġrealm Ġwas Ġsuccessful . ĠClients Ġcan Ġnow Ġuse Ġthe Ġsession Ġto Ġmake Ġvarious ĠW AMP Ġrelated Ġthings ĊĠĠĠĠĠĠĠĠ Ġ* Ġlike Ġpub / sub Ġand ĠRPC . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġon Realm Joined ( realm : ĠString ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġrealm Ġhas Ġbeen Ġleft Ġsuccessfully . ĠThe Ġonly Ġthing Ġthat Ġcan Ġbe Ġdone Ġafterwards Ġis Ġjoining Ġa Ġrealm Ġor Ġshut ting Ġthe Ġsession Ġdown . ĊĠĠĠĠĠĠĠĠ Ġ* ĠEverything Ġelse Ġwill Ġlead Ġto Ġan Ġaborted Ġsession . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġfrom Router Ġ` ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġon Realm Left ( realm : ĠString , Ġfrom Router : ĠBoolean ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĠThe Ġsession Ġwas Ġclosed Ġnormally Ġand Ġis Ġnow Ġin Ġa Ġterminal Ġstate . ĠUsing Ġit Ġ( for Ġexample Ġjoining Ġa Ġrealm ) ĊĠĠĠĠĠĠĠĠ Ġ* Ġwill Ġalways Ġlead Ġto Ġ[ on Session Abort ed ] Ġbeing Ġcalled . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġon Session Shutdown () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġsession Ġwas Ġclosed Ġab norm ally , Ġeither Ġdue Ġto Ġunexpected ĠAPI Ġusage Ġ( e . g . Ġleaving Ġa Ġrealm Ġbefore Ġjoining Ġa Ġrealm ) ĊĠĠĠĠĠĠĠĠ Ġ* Ġor Ġdue Ġto Ġunexpected Ġmessages Ġfrom Ġthe ĠW AMP Ġrouter . ĠThe Ġsession Ġis Ġin Ġa Ġterminal Ġstate Ġafterwards . ĊĠĠĠĠĠĠĠĠ Ġ* ĠUsing Ġit Ġ( for Ġexample Ġjoining Ġa Ġrealm ) Ġwill Ġalways Ġlead Ġto Ġ[ on Session Abort ed ] Ġbeing Ġcalled . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġon Session Abort ed ( reason : ĠString , Ġthrowable : ĠThrowable ?) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġenum Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠ ĠINITIAL , ĊĠĠĠĠĠĠĠ ĠJOIN ING , ĊĠĠĠĠĠĠĠ ĠJOIN ED , ĊĠĠĠĠĠĠĠ ĠAB ORT ED , ĊĠĠĠĠĠĠĠ ĠLE AV ING , ĊĠĠĠĠĠĠĠ ĠSH UT TING _ DOWN , ĊĠĠĠĠĠĠĠ ĠSH UT _ DOWN ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsealed Ġclass ĠTrigger Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠMessage Received ( val Ġmessage : ĠMessage ) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġobject ĠBinary Message Received Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠJoin ( val Ġrealm : ĠString ) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠSubscribe ( val Ġtopic : ĠString , Ġval Ġevent Channel : ĠSend Channel < Subscription Event >) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠUn subscribe ( val Ġsubscription Id : ĠSubscription Id ) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠRegister ( val Ġprocedure Id : ĠProcedure Id , Ġval Ġevent Channel : ĠSend Channel < Cal lee Event >) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠUn register ( val Ġregistration Id : ĠRegistration Id ) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠCall ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprocedure Id : ĠProcedure Id , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments Kw : ĠJsonObject ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Channel : ĠSend Channel < Caller Event > ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠTrigger () ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠY ield ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠrequestId : ĠRequest Id , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments Kw : ĠJsonObject ? ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠTrigger () ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠError ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Type : ĠMessageType , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠrequestId : ĠRequest Id , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw amp Error Uri : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments : ĠJson Array ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments Kw : ĠJsonObject ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠTrigger () ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠPublish ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtopic : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments Kw : ĠJsonObject ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġacknowledge : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Channel : ĠSend Channel < Publication Event > ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠTrigger () ĊĊĠĠĠĠĠĠĠ Ġobject ĠLeave Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġobject ĠShutdown Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġclass ĠWebSocket Closed ( val Ġcode : ĠInt , Ġval Ġreason : ĠString ) Ġ: ĠTrigger () ĊĠĠĠĠĠĠĠ Ġclass ĠWebSocket Failed ( val Ġthrowable : ĠThrowable ) Ġ: ĠTrigger () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġmutex Ġ= ĠMutex () ĊĠĠĠ Ġ// ĠINTERNAL ĠSTATE ĠMUST ĠONLY ĠBE ĠMUT ATED ĠWHEN ĠA BO VE ĠMUT EX ĠIS ĠLOCK ED ĊĠĠĠ Ġprivate Ġvar Ġrealm : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġstate Ġ= ĠINITIAL ĊĠĠĠ Ġprivate Ġval Ġpending Subscriptions Ġ= Ġmutable Map Of < RequestId , ĠSend Channel < Subscription Event >>() ĊĠĠĠ Ġprivate Ġval Ġpending Un subscriptions Ġ= Ġmutable Map Of < RequestId , ĠPair < Subscription Id , ĠSend Channel < Subscription Event >> >() ĊĠĠĠ Ġprivate Ġval Ġsubscriptions Ġ= Ġmutable Map Of < Subscription Id , ĠSend Channel < Subscription Event >>() ĊĠĠĠ Ġprivate Ġval Ġpending Regist rations Ġ= Ġmutable Map Of < RequestId , ĠSend Channel < Cal lee Event >>() ĊĠĠĠ Ġprivate Ġval Ġpending Un regist rations Ġ= Ġmutable Map Of < RequestId , ĠPair < Registration Id , ĠSend Channel < Cal lee Event >> >() ĊĠĠĠ Ġprivate Ġval Ġregist rations Ġ= Ġmutable Map Of < Registration Id , ĠSend Channel < Cal lee Event >>() ĊĠĠĠ Ġprivate Ġval Ġpending Calls Ġ= Ġmutable Map Of < RequestId , ĠSend Channel < Caller Event >>() ĊĠĠĠ Ġprivate Ġval Ġpending Public ations Ġ= Ġmutable Map Of < RequestId , ĠSend Channel < Publication Event >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠJoin s Ġthe Ġgiven ĠW AMP Ġrealm . ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠNote : ĠIt Ġcan Ġtake Ġsome Ġtime Ġbefore Ġthe Ġactual Ġoperation Ġhas Ġbeen Ġperformed Ġby Ġthe Ġrouter . ĊĠĠĠĠ Ġ* ĠImplement Ġ[ W amp Session Listener . on Realm Joined ] Ġif Ġyou Ġwant Ġto Ġknow Ġwhen Ġthat Ġhas Ġhappened . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġthis Ġsession Ġis Ġnot Ġin Ġthe Ġinitial Ġstate Ġ( i . e . Ġdirectly Ġafter Ġit Ġhas Ġbeen Ġcreated ĠOR Ġafter Ġleaving Ġa Ġrealm ) Ġthis Ġwill ĊĠĠĠĠ Ġ* Ġabort Ġthe Ġsession . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġjoin ( realm : ĠString ): ĠUnit Ġ= Ġdispatch ( Join ( realm )) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLe aves Ġthe Ġcurrently Ġjoined ĠW AMP Ġrealm . ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠNote : ĠIt Ġcan Ġtake Ġsome Ġtime Ġbefore Ġthe Ġactual Ġoperation Ġhas Ġbeen Ġperformed Ġby Ġthe Ġrouter . ĊĠĠĠĠ Ġ* ĠImplement Ġ[ W amp Session Listener . on Realm Left ] Ġif Ġyou Ġwant Ġto Ġknow Ġwhen Ġthat Ġhas Ġhappened . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġcall Ġleaves Ġthe ĠWebSocket Ġopen Ġso Ġyou Ġcan Ġcall Ġ[ join ] Ġagain Ġonce Ġ[ W amp Session Listener . on Realm Left ] ĊĠĠĠĠ Ġ* Ġhas Ġbeen Ġcalled Ġto Ġjoin Ġa Ġnew Ġrealm . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġthis Ġsession Ġhas Ġnot Ġjoined Ġa Ġrealm Ġyet Ġthis Ġwill ĊĠĠĠĠ Ġ* Ġabort Ġthe Ġsession . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġleave (): ĠUnit Ġ= Ġdispatch ( Leave ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSame Ġas Ġ[ leave ] Ġbut Ġyou Ġwill Ġnot Ġbe Ġable Ġto Ġjoin Ġanother Ġrealm . ĠThe Ġsession Ġbecomes Ġun usable Ġafter Ġshutdown , Ġthe ĠWebSocket ĊĠĠĠĠ Ġ* Ġis Ġclosed . ĊĠĠĠĠ Ġ* ĠImplement Ġ[ W amp Session Listener . on Session Shutdown ] Ġif Ġyou Ġwant Ġto Ġknow Ġwhen Ġshutdown Ġhas Ġbeen Ġacknowled ged Ġby Ġthe Ġrouter . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNote : ĠCalling Ġthis Ġwill Ġalso Ġnotify Ġ[ W amp Session Listener . on Realm Left ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġshutdown (): ĠUnit Ġ= Ġdispatch ( Shutdown ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSubscribe Ġto Ġthe Ġgiven Ġtopic . ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠNote : ĠThe Ġsubscription Ġneeds Ġto Ġbe Ġacknowled ged Ġby Ġthe Ġrouter , Ġwhich Ġcan Ġtake Ġsome Ġtime . ĊĠĠĠĠ Ġ* ĠUse Ġthe Ġreturned Ġ[ Receive Channel ] Ġto Ġprocess Ġall Ġrelated Ġ[ Subscription Event ] s . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġsubscribe ( topic : ĠString ): ĠReceive Channel < Subscription Event > Ġ= ĊĠĠĠĠĠĠĠ ĠChannel < Subscription Event >(). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdispatch ( Subscribe ( topic , Ġit )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUn subscribe Ġfrom Ġthe Ġgiven Ġ[ Subscription Id ]. ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠNote : ĠThe Ġun subscription Ġneeds Ġto Ġbe Ġacknowled ged Ġby Ġthe Ġrouter , Ġwhich Ġcan Ġtake Ġsome Ġtime . ĊĠĠĠĠ Ġ* ĠEvents Ġrelated Ġto Ġthis Ġun subscription Ġare Ġsent Ġto Ġthe Ġchannel Ġyou Ġgot Ġvia Ġ[ subscribe ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġunsubscribe ( subscriptionId : ĠSubscription Id ) Ġ= Ġdispatch ( Un subscribe ( subscriptionId )) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPublish Ġsomething Ġto Ġthe Ġgiven Ġtopic . ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠBy Ġdefault Ġthese Ġevents Ġare Ġnot Ġacknowled ged . ĠSet Ġ[ ack nowledge ] Ġto Ġ` true ` Ġif Ġyou Ġwant Ġacknowledge ments . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġ[ ack nowledge ] Ġis Ġ` true ` Ġyou Ġcan Ġuse Ġthe Ġreturned Ġ[ Receive Channel ] Ġto Ġfind Ġout Ġif Ġthe Ġevent Ġhas Ġbeen Ġpublished Ġor Ġnot . ĊĠĠĠĠ Ġ* ĠIf Ġit Ġis Ġ` false ` Ġthe Ġchannel Ġwill Ġbe Ġclosed Ġimmediately Ġafter Ġsending Ġthe Ġevent Ġto Ġthe Ġbroker . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġpublish ( ĊĠĠĠĠĠĠĠ Ġtopic : ĠString , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġacknowledge : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġ): ĠReceive Channel < Publication Event > Ġ= ĠChannel < Publication Event >(). also Ġ{ ĊĠĠĠĠĠĠĠ Ġdispatch ( Publish ( topic , Ġarguments , Ġarguments Kw , Ġacknowledge , Ġit )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegister Ġa Ġprocedure Ġwith Ġthe Ġdeal er . ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠNote : ĠThe Ġregistration Ġneeds Ġto Ġbe Ġacknowled ged Ġby Ġthe Ġrouter , Ġwhich Ġcan Ġtake Ġsome Ġtime . ĊĠĠĠĠ Ġ* ĠUse Ġthe Ġreturned Ġ[ Receive Channel ] Ġto Ġprocess Ġall Ġrelated Ġ[ Cal lee Event ] s . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ* Attention *: ĠMake Ġsure Ġto Ġalways Ġcall Ġthe Ġ[ Cal lee Event . Invocation . return Result ] Ġlambda Ġwhen Ġhandling Ġinv ocations . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġregister ( procedure Id : ĠProcedure Id ): ĠReceive Channel < Cal lee Event > Ġ= ĊĠĠĠĠĠĠĠ ĠChannel < Cal lee Event >(). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdispatch ( Register ( procedure Id , Ġit )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUn register Ġthe Ġgiven Ġ[ Registration Id ]. ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠNote : ĠThe Ġun registration Ġneeds Ġto Ġbe Ġacknowled ged Ġby Ġthe Ġrouter , Ġwhich Ġcan Ġtake Ġsome Ġtime . ĊĠĠĠĠ Ġ* ĠEvents Ġrelated Ġto Ġthis Ġun registration Ġare Ġsent Ġto Ġthe Ġchannel Ġyou Ġgot Ġvia Ġ[ register ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġunregister ( registration Id : ĠRegistration Id ): ĠUnit Ġ= Ġdispatch ( Unregister ( registration Id )) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCall Ġa Ġremote Ġprocedure . ĠS usp ends Ġuntil Ġthe Ġmessage Ġhas Ġbeen Ġpassed Ġto Ġthe ĠWebSocket . ĊĠĠĠĠ Ġ* ĠUse Ġthe Ġreturned Ġ[ Receive Channel ] Ġto Ġprocess Ġall Ġrelated Ġ[ Caller Event ] s . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġcall ( ĊĠĠĠĠĠĠĠ Ġprocedure Id : ĠProcedure Id , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ? Ġ= Ġnull ĊĠĠĠ Ġ): ĠReceive Channel < Caller Event > Ġ= ĊĠĠĠĠĠĠĠ ĠChannel < Caller Event >(). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdispatch ( Call ( procedure Id , Ġarguments , Ġarguments Kw , Ġit )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluate ( trigger : ĠTrigger ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! ensure Non Binary Message ( trigger )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSH UT TING _ DOWN Ġ-> Ġevaluate Le aving Or Shut ting Down ( trigger , Ġmust Shutdown Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠINITIAL ĠĠĠĠĠĠ Ġ-> Ġevaluate Initial ( trigger ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJOIN ING ĠĠĠĠĠĠ Ġ-> Ġevaluate Join ing ( trigger ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJOIN ED ĠĠĠĠĠĠĠ Ġ-> Ġevaluate Joined ( trigger ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAB ORT ED ĠĠĠĠĠĠ Ġ-> Ġevaluated Abort ed ( trigger ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLE AV ING ĠĠĠĠĠĠ Ġ-> Ġevaluate Le aving Or Shut ting Down ( trigger , Ġmust Shutdown Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSH UT _ DOWN ĠĠĠĠ Ġ-> Ġevaluate Shutdown ( trigger ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Id ( trigger ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġensure Non Binary Message ( trigger : ĠTrigger ) Ġ= Ġif Ġ( trigger Ġis ĠBinary Message Received ) Ġ{ ĊĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received Ġbinary Ġmessage . ĠThis Ġis Ġnot Ġsupported Ġby Ġthis Ġclient .") ĊĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠ Ġ} Ġelse Ġtrue ĊĊĠĠĠ Ġ// Ġwe Ġneed Ġthese ĠIDs Ġonly Ġuntil Ġwe 've Ġreceived Ġthem Ġback Ġfrom Ġthe Ġbroker Ġfor Ġcorrelation ĊĠĠĠ Ġprivate Ġfun Ġrelease Id ( trigger : ĠTrigger ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( trigger Ġis ĠMessage Received Ġ&& Ġtrigger . message Ġis ĠRequest Message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Generator . release Id ( trigger . message . requestId ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluate Shutdown ( trigger : ĠTrigger ) Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ( trigger ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage Received Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( trigger . message Ġ! is ĠMessage . Error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Session Ġis Ġshut Ġdown . ĠWe Ġcannot Ġprocess Ġmessages .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUnit Ġ// Ġignore Ġerrors ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠWebSocket Closed Ġ-> ĠUnit Ġ// Ġwe Ġcaused Ġthis Ġourselves ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠWebSocket Failed Ġ-> Ġon WebSocket Failed ( trigger . throwable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠShutdown ĠĠĠĠĠĠĠ Ġ-> ĠUnit Ġ// Ġalready Ġshutdown ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġfail Transition ( trigger ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluate Le aving Or Shut ting Down ( trigger : ĠTrigger , Ġmust Shutdown : ĠBoolean ) Ġ= Ġwhen Ġ( trigger ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠMessage Received Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( trigger . message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Good bye Ġ-> Ġon Good bye Ack nowled ged Received ( must Shutdown ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> ĠUnit Ġ// Ġaccording Ġto Ġthe Ġspec Ġwe Ġare Ġto Ġignore Ġother Ġmessages ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Closed Ġ-> Ġon WebSocket Closed Prem ature ly ( trigger . code , Ġtrigger . reason ) ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Failed Ġ-> Ġdo On WebSocket Failed ( trigger . throwable ) ĊĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġfail Transition ( trigger ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluated Abort ed ( trigger : ĠTrigger ) Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ( trigger ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠWebSocket Closed , Ġis ĠWebSocket Failed Ġ-> ĠUnit Ġ// Ġwe Ġdon 't Ġeven Ġcare Ġanymore ! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠShutdown ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> ĠUnit Ġ// Ġignore Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġfail Transition ( trigger ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluate Joined ( trigger : ĠTrigger ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( trigger ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage Received Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġmessage Ġ= Ġtrigger . message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Un subscribed Ġ-> Ġon Un subscribed Received ( message . requestId ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Sub scribed ĠĠ Ġ-> Ġon Sub scribed Received ( message . requestId , Ġmessage . subscriptionId ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Event ĠĠĠĠĠĠĠ Ġ-> Ġon Event Received ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . subscriptionId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . arguments Kw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Published ĠĠĠ Ġ-> Ġon Published Received ( message . requestId , Ġmessage . publication Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Registered ĠĠ Ġ-> Ġon Registered Received ( message . requestId , Ġmessage . registration Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Un registered Ġ-> Ġon Un registered Received ( message . requestId ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Invocation ĠĠ Ġ-> Ġon Invocation Received ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . registration Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . requestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . arguments Kw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Result ĠĠĠĠĠĠ Ġ-> Ġon Result Received ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . requestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . arguments Kw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Error ĠĠĠĠĠĠĠ Ġ-> ĠonError Received ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . original Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . requestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . w amp Error Uri ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Good bye ĠĠĠĠĠ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( message . reason Ġ!= ĠW amp Close . GOO DB YE _ AND _ OUT . content ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Good bye Received ( must Shutdown Ġ= Ġmessage . reason Ġ== ĠW amp Close . SYSTEM _ SHUT DOWN . content ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Abort ĠĠĠĠĠĠĠ Ġ-> Ġon Abort ( reason Ġ= Ġmessage . reason , Ġthrowable Ġ= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġon Protocol Vi olated () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠSubscribe ĠĠĠĠĠĠ Ġ-> Ġsetup Subscription ( trigger . topic , Ġtrigger . event Channel ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠUn subscribe ĠĠĠĠ Ġ-> Ġdo Un subscribe ( trigger . subscriptionId ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPublish ĠĠĠĠĠĠĠĠ Ġ-> Ġdo Publish ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . topic , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . arguments Kw , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . ack nowledge , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . event Channel ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRegister ĠĠĠĠĠĠĠ Ġ-> Ġdo Register ( trigger . procedure Id , Ġtrigger . event Channel ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠUn register ĠĠĠĠĠ Ġ-> Ġdo Unregister ( trigger . registration Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCall ĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġdo Call ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . procedure Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . arguments Kw , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . event Channel ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠY ield ĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġdo Yield ( trigger . requestId , Ġtrigger . arguments , Ġtrigger . arguments Kw ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLeave ĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġsend Good bye ( must Shutdown Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠShutdown ĠĠĠĠĠĠĠ Ġ-> Ġsend Good bye ( must Shutdown Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠError ĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġsend Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . error Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . requestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . w amp Error Uri , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrigger . arguments Kw ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠWebSocket Closed Ġ-> Ġon WebSocket Closed Prem ature ly ( trigger . code , Ġtrigger . reason ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠWebSocket Failed Ġ-> Ġon WebSocket Failed ( trigger . throwable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġfail Transition ( trigger ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Yield ( requestId : ĠRequest Id , Ġarguments : ĠJson Array ?, Ġarguments Kw : ĠJsonObject ?) Ġ= ĊĠĠĠĠĠĠĠ Ġsend ( Message . Yield ( requestId , Ġarguments , Ġarguments Kw )) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Unregister ( registration Id : ĠRegistration Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= Ġregist rations . remove ( registration Id ) ĊĠĠĠĠĠĠĠ Ġif Ġ( channel Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠrequestId Ġ= Ġid Generator . new Id () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Un regist rations [ requestId ] Ġ= Ġregistration Id Ġto Ġchannel ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend ( Message . Unregister ( requestId , Ġregistration Id )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Register ( procedure Id : ĠProcedure Id , Ġevent Channel : ĠSend Channel < Cal lee Event >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠrequestId Ġ= Ġid Generator . new Id () ĊĠĠĠĠĠĠĠ Ġpending Regist rations [ requestId ] Ġ= Ġevent Channel ĊĠĠĠĠĠĠĠ Ġsend ( Message . Register ( requestId , Ġprocedure Id )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Call ( ĊĠĠĠĠĠĠĠ Ġprocedure Id : ĠProcedure Id , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ?, ĊĠĠĠĠĠĠĠ Ġevent Channel : ĠSend Channel < Caller Event > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠrequestId Ġ= Ġid Generator . new Id () ĊĠĠĠĠĠĠĠ Ġpending Calls [ requestId ] Ġ= Ġevent Channel ĊĠĠĠĠĠĠĠ Ġsend ( Message . Call ( requestId , Ġprocedure Id , Ġarguments , Ġarguments Kw )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend Error ( ĊĠĠĠĠĠĠĠ Ġerror Type : ĠMessageType , ĊĠĠĠĠĠĠĠ ĠrequestId : ĠRequest Id , ĊĠĠĠĠĠĠĠ Ġw amp Error Uri : ĠString , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ? ĊĠĠĠ Ġ) Ġ= ĊĠĠĠĠĠĠĠ Ġsend ( Message . Error ( requestId , Ġerror Type , Ġw amp Error Uri , Ġarguments Ġ= Ġarguments , Ġarguments Kw Ġ= Ġarguments Kw )) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Result Received ( requestId : ĠRequest Id , Ġarguments : ĠJson Array ?, Ġarguments Kw : ĠJsonObject ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Calls . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠRESULT Ġthat Ġwe Ġhave Ġno Ġpending Ġcall Ġfor . ĠRequest Id Ġ= Ġ$ requestId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevent Channel . send Async ( Caller Event . Call Succeeded ( arguments , Ġarguments Kw ), Ġclose Ġ= Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Invocation Received ( ĊĠĠĠĠĠĠĠ Ġregistration Id : ĠRegistration Id , ĊĠĠĠĠĠĠĠ ĠrequestId : ĠRequest Id , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġregist rations [ registration Id ] ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpending Un registration Ids Ġ= Ġpending Un regist rations . values . map Ġ{ Ġit . first Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( registration Id Ġ! in Ġpending Un registration Ids ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠIN VOC ATION Ġthat Ġwe Ġhave Ġno Ġregistration Ġor Ġpending Ġun registration Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠRegistration Id Ġ= Ġ$ registration Id ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevent Channel . send Async ( Cal lee Event . Invocation ( arguments , Ġarguments Kw ) Ġ{ Ġyield Result ( requestId , Ġit ) Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġyield Result ( requestId : ĠRequest Id , Ġresult : ĠCall er Event ) Ġ= ĊĠĠĠĠĠĠĠ Ġdispatch ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCall er Event . Call Failed Ġ-> ĠError ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Invocation . type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠrequestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . error Uri , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . arguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . arguments Kw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCall er Event . Call Succeeded Ġ-> ĠY ield ( requestId , Ġresult . arguments , Ġresult . arguments Kw ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Registered Received ( requestId : ĠRequest Id , Ġregistration Id : ĠRegistration Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Regist rations . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠREG ISTER ED Ġthat Ġwe Ġhave Ġno Ġpending Ġregistration Ġfor . ĠRequest Id Ġ= Ġ$ requestId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġregist rations [ registration Id ] Ġ= Ġevent Channel ĊĠĠĠĠĠĠĠ Ġevent Channel . send Async ( Cal lee Event . Procedure Registered ( registration Id )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Publish ( ĊĠĠĠĠĠĠĠ Ġtopic : ĠString , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ?, ĊĠĠĠĠĠĠĠ Ġacknowledge : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġevent Channel : ĠSend Channel < Publication Event > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠrequestId Ġ= Ġid Generator . new Id () ĊĠĠĠĠĠĠĠ Ġif Ġ( ack nowledge ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Public ations [ requestId ] Ġ= Ġevent Channel ĊĊĠĠĠĠĠĠĠ Ġsend ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Publish ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠrequestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtopic Ġ= Ġtopic , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarguments Ġ= Ġarguments , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarguments Kw Ġ= Ġarguments Kw , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions Ġ= Ġif Ġ( ack nowledge ) Ġbuild JsonObject Ġ{ Ġput ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ack nowledge ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ} Ġelse Ġempty JsonObject ())) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! ack nowledge ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevent Channel . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Un subscribe ( subscriptionId : ĠSubscription Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= Ġsubscriptions . remove ( subscriptionId ) ĊĠĠĠĠĠĠĠ Ġ// Ġdon 't Ġsend Ġa Ġrequest Ġif Ġwe Ġdon 't Ġeven Ġhave Ġa Ġlocal Ġsubscriber Ġrunning ĊĠĠĠĠĠĠĠ Ġif Ġ( channel Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠrequestId Ġ= Ġid Generator . new Id () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Un subscriptions [ requestId ] Ġ= Ġsubscription Id Ġto Ġchannel ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend ( Message . Un subscribe ( requestId , Ġsubscription Id )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsetup Subscription ( topic : ĠString , Ġevent Channel : ĠSend Channel < Subscription Event >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠrequestId Ġ= Ġid Generator . new Id () ĊĠĠĠĠĠĠĠ Ġpending Subscriptions [ requestId ] Ġ= Ġevent Channel ĊĠĠĠĠĠĠĠ Ġsend Subscribe ( requestId , Ġtopic ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend Subscribe ( requestId : ĠRequest Id , Ġtopic : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠMessage . Subscribe ( requestId , Ġtopic ) ĊĠĠĠĠĠĠĠ Ġsend ( message ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun ĠonError Received ( ĊĠĠĠĠĠĠĠ Ġerror Type : ĠMessageType , ĊĠĠĠĠĠĠĠ ĠrequestId : ĠRequest Id , ĊĠĠĠĠĠĠĠ Ġw amp Error Uri : ĠString ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( error Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Un subscribe . type Ġ-> Ġfail Un subscription ( requestId , Ġw amp Error Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Unregister . type Ġ Ġ-> Ġfail Un registration ( requestId , Ġw amp Error Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Publish . type ĠĠĠĠ Ġ-> Ġfail Publication ( requestId , Ġw amp Error Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Subscribe . type ĠĠ Ġ-> Ġfail Subscription ( requestId , Ġw amp Error Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Register . type ĠĠĠ Ġ-> Ġfail Registration ( requestId , Ġw amp Error Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Call . type ĠĠĠĠĠĠĠ Ġ-> Ġfail Call ( requestId , Ġw amp Error Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġon Protocol Vi olated (" Received Ġinvalid ĠREQUEST . ĠType : Ġ$ error Type ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Publication ( requestId : ĠRequest Id , Ġw amp Error Uri : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Public ations . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠP UB L ISH ĠERROR Ġthat Ġwe Ġhave Ġno Ġpending Ġpublication Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠERROR Ġuri Ġ= Ġ$ w amp Error Uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfail Publication ( w amp Error Uri , Ġevent Channel ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Call ( requestId : ĠRequest Id , Ġw amp Error Uri : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Calls . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠCALL ĠERROR Ġthat Ġwe Ġhave Ġno Ġpending Ġcall Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠERROR Ġuri Ġ= Ġ$ w amp Error Uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfail Call ( w amp Error Uri , Ġevent Channel ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Registration ( requestId : ĠRequest Id , Ġw amp Error Uri : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Regist rations . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠREG ISTER ĠERROR Ġthat Ġwe Ġhave Ġno Ġpending Ġregistration Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠERROR Ġuri Ġ= Ġ$ w amp Error Uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfail Registration ( w amp Error Uri , Ġevent Channel ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Un registration ( requestId : ĠRequest Id , Ġw amp Error Uri : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Un regist rations . remove ( requestId )?. second ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠUN REGISTER ĠERROR Ġthat Ġwe Ġhave Ġno Ġpending Ġun registration Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠERROR Ġuri Ġ= Ġ$ w amp Error Uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfail Un registration ( w amp Error Uri , Ġevent Channel ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Un subscription ( requestId : ĠRequest Id , Ġw amp Error Uri : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Un subscriptions . remove ( requestId )?. second ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠUNS UB SCR IBE ĠERROR Ġthat Ġwe Ġhave Ġno Ġpending Ġun subscription Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠERROR Ġuri Ġ= Ġ$ w amp Error Uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfail Un subscription ( w amp Error Uri , Ġevent Channel ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Subscription ( requestId : ĠRequest Id , Ġw amp Error Uri : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Subscriptions . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠSUB SCR IBE ĠERROR Ġthat Ġwe Ġhave Ġno Ġpending Ġsubscription Ġfor . ĠRequest Id Ġ= Ġ$ requestId ĠERROR Ġuri Ġ= Ġ$ w amp Error Uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfail Subscription ( w amp Error Uri , Ġevent Channel ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfail Un registration ( error Uri : ĠString , Ġchannel : ĠSend Channel < Cal lee Event >) Ġ= ĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Cal lee Event . Un registration Failed ( error Uri ), Ġclose Ġ= Ġtrue ) ĊĊĠĠĠ Ġprivate Ġfun Ġfail Un subscription ( error Uri : ĠString , Ġchannel : ĠSend Channel < Subscription Event >) Ġ= ĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Subscription Event . Un subscription Failed ( error Uri ), Ġclose Ġ= Ġtrue ) ĊĊĠĠĠ Ġprivate Ġfun Ġfail Subscription ( error Uri : ĠString , Ġchannel : ĠSend Channel < Subscription Event >) Ġ= ĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Subscription Event . Subscription Failed ( error Uri ), Ġclose Ġ= Ġtrue ) ĊĊĠĠĠ Ġprivate Ġfun Ġfail Call ( error Uri : ĠString , Ġchannel : ĠSend Channel < Caller Event >) Ġ= ĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Caller Event . Call Failed ( error Uri ), Ġclose Ġ= Ġtrue ) ĊĊĠĠĠ Ġprivate Ġfun Ġfail Publication ( error Uri : ĠString , Ġchannel : ĠSend Channel < Publication Event >) Ġ= ĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Publication Event . Publication Failed ( error Uri ), Ġclose Ġ= Ġtrue ) ĊĊĠĠĠ Ġprivate Ġfun Ġfail Registration ( error Uri : ĠString , Ġchannel : ĠSend Channel < Cal lee Event >) Ġ= ĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Cal lee Event . Registration Failed ( error Uri ), Ġclose Ġ= Ġtrue ) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Published Received ( requestId : ĠRequest Id , Ġpublication Id : ĠPublic ation Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Public ations . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠP UB L ISHED Ġthat Ġwe Ġhave Ġno Ġpending Ġpublication Ġfor . ĠRequest Id Ġ= Ġ$ requestId Ġpublication Id Ġ= Ġ$ publication Id ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevent Channel . send Async ( Publication Event . Publication Succeeded ( publication Id ), Ġclose Ġ= Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Event Received ( ĊĠĠĠĠĠĠĠ Ġsubscription Id : ĠSubscription Id , ĊĠĠĠĠĠĠĠ Ġarguments : ĠJson Array ?, ĊĠĠĠĠĠĠĠ Ġarguments Kw : ĠJsonObject ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġsubscriptions [ subscriptionId ] ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpending Un subscription Ids Ġ= Ġpending Un subscriptions . values . map Ġ{ Ġit . first Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( subscriptionId Ġ! in Ġpending Un subscription Ids ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠEVENT Ġthat Ġwe Ġhave Ġno Ġsubscription Ġor Ġpending Ġun subscription Ġfor . ĠSubscription Id Ġ= Ġ$ subscriptionId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevent Channel . send Async ( Subscription Event . Payload ( arguments , Ġarguments Kw )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Sub scribed Received ( requestId : ĠRequest Id , Ġsubscription Id : ĠSubscription Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Channel Ġ= Ġpending Subscriptions . remove ( requestId ) ĊĠĠĠĠĠĠĠ Ġif Ġ( event Channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠSUB SCR IB ED Ġthat Ġwe Ġhave Ġno Ġpending Ġsubscription Ġfor . ĠRequest Id Ġ= Ġ$ requestId Ġsubscription Id Ġ= Ġ$ subscriptionId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsubscriptions [ subscriptionId ] Ġ= Ġevent Channel ĊĠĠĠĠĠĠĠ Ġevent Channel . send Async ( Subscription Event . Subscription Est ab lished ( subscriptionId )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Un subscribed Received ( requestId : ĠRequest Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= Ġpending Un subscriptions . remove ( requestId )?. second ĊĠĠĠĠĠĠĠ Ġif Ġ( channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠUNS UB SCR IB ED Ġthat Ġwe Ġhave Ġno Ġpending Ġun subscription Ġfor . ĠRequest Id Ġ= Ġ$ requestId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Subscription Event . Subscription Closed , Ġclose Ġ= Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Un registered Received ( requestId : ĠRequest Id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= Ġpending Un regist rations . remove ( requestId )?. second ĊĠĠĠĠĠĠĠ Ġif Ġ( channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Received ĠUN REGISTER ED Ġthat Ġwe Ġhave Ġno Ġpending Ġun registration Ġfor . ĠRequest Id Ġ= Ġ$ requestId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġchannel . send Async ( Cal lee Event . Procedure Un registered , Ġclose Ġ= Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluate Join ing ( trigger : ĠTrigger ) Ġ= Ġwhen Ġ( trigger ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠLeave , Ġis ĠShutdown Ġ-> Ġsend Abort ( W amp Close . SYSTEM _ SHUT DOWN ) ĊĠĠĠĠĠĠĠ Ġis ĠMessage Received ĠĠĠ Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( trigger . message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Welcome Ġ-> Ġon Welcome Received () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMessage . Abort ĠĠ Ġ-> Ġon Abort ( trigger . message . reason ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġon Protocol Vi olated (" Illegal Ġmessage Ġreceived . ĠExpected Ġ' Welcome ' Ġor Ġ' Abort '. ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Closed ĠĠĠ Ġ-> Ġon WebSocket Closed Prem ature ly ( trigger . code , Ġtrigger . reason ) ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Failed ĠĠĠ Ġ-> Ġon WebSocket Failed ( trigger . throwable ) ĊĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġfail Transition ( trigger ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġon Welcome Received () Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠJOIN ED ĊĠĠĠĠĠĠĠ Ġsession Listener ?. on Realm Joined ( realm !! ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Good bye Ack nowled ged Received ( must Shutdown : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= Ġif Ġ(! must Shutdown ) ĠINITIAL Ġelse ĠSH UT _ DOWN ĊĠĠĠĠĠĠĠ Ġnotify Realm Left ( from Router Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠ Ġif Ġ( must Shutdown ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Shutdown () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Realm Left ( from Router : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsession Listener ?. on Realm Left ( realm !! , Ġfrom Router ) ĊĠĠĠĠĠĠĠ Ġclear Channels ( W amp Close . CLOSE _ REAL M . content ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Good bye Received ( must Shutdown : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= Ġif Ġ(! must Shutdown ) ĠINITIAL Ġelse ĠSH UT _ DOWN ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠMessage . Good bye ( reason Ġ= ĠW amp Close . GOO DB YE _ AND _ OUT . content ) ĊĠĠĠĠĠĠĠ Ġsend ( message ) ĊĠĠĠĠĠĠĠ Ġnotify Realm Left ( from Router Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġif Ġ( must Shutdown ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Shutdown () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Shutdown () Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠSH UT _ DOWN ĊĠĠĠĠĠĠĠ Ġsession Listener ?. on Session Shutdown () ĊĠĠĠĠĠĠĠ Ġclose WebSocket () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Abort ( reason : ĠString , Ġthrowable : ĠThrowable ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠAB ORT ED ĊĠĠĠĠĠĠĠ Ġnotify Session Abort ( reason , Ġthrowable ) ĊĠĠĠĠĠĠĠ Ġweb Socket Delegate . close ( WebSocket Close Codes . NORMAL _ CLO S URE , Ġ" ABORT ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġevaluate Initial ( trigger : ĠTrigger ) Ġ= Ġwhen Ġ( trigger ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠMessage Received Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( trigger . message Ġ! is ĠMessage . Error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Protocol Vi olated (" Not Ġready Ġto Ġreceive Ġmessages Ġyet . ĠSession Ġhas Ġnot Ġbeen Ġestablished .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUnit Ġ// Ġignore Ġerrors ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠJoin ĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġsend Hello ( trigger . realm ) ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Closed Ġ-> Ġon WebSocket Closed Prem ature ly ( trigger . code , Ġtrigger . reason ) ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Failed Ġ-> Ġon WebSocket Failed ( trigger . throwable ) ĊĠĠĠĠĠĠĠ Ġis ĠShutdown ĠĠĠĠĠĠĠ Ġ-> Ġdo Shutdown () ĊĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġfail Transition ( trigger ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo On WebSocket Failed ( throwable : ĠThrowable ) Ġ= Ġon Abort (" WebSocket Ġfailed ", Ġthrowable ) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon WebSocket Closed Prem ature ly ( code : ĠInt , Ġreason : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ Ġon Abort (" WebSocket Ġclosed Ġprem ature ly Ġ($ code Ġ- Ġ$ reason )") ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġfail Transition ( trigger : ĠTrigger ) Ġ= Ġon Abort (" Invalid Ġstate Ġtrigger Ġ$ trigger Ġfor Ġstate Ġ$ state ") ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend Good bye ( must Shutdown : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= Ġif Ġ(! must Shutdown ) ĠLE AV ING Ġelse ĠSH UT TING _ DOWN ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMessage . Good bye ( reason Ġ= Ġif Ġ( must Shutdown ) ĠW amp Close . SYSTEM _ SHUT DOWN . content Ġelse ĠW amp Close . CLOSE _ REAL M . content ) ĊĠĠĠĠĠĠĠ Ġsend ( message ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Protocol Vi olated ( message : ĠString Ġ= Ġ" Received Ġunexpected Ġmessage .") Ġ= ĊĠĠĠĠĠĠĠ Ġsend Abort ( W amp Close . PROTOCOL _ VI OL ATION , Ġmessage ) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend Abort ( reason : ĠW amp Close , Ġmessage : ĠString ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠAB ORT ED ĊĠĠĠĠĠĠĠ Ġnotify Session Abort ( reason . content Ġ+ Ġ( message ?. let Ġ{ Ġ" Ġ: Ġ$ it " Ġ} Ġ?: Ġ""), Ġnull ) ĊĠĠĠĠĠĠĠ Ġval Ġdetails Ġ= Ġmessage ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuild JsonObject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" message ", Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġempty JsonObject () ĊĠĠĠĠĠĠĠ Ġval Ġabort Message Ġ= ĠMessage . Abort ( reason Ġ= Ġreason . content , Ġdetails Ġ= Ġdetails ) ĊĠĠĠĠĠĠĠ Ġsend ( abort Message ) ĊĠĠĠĠĠĠĠ Ġweb Socket Delegate . close ( reason . web Socket Close Code , Ġ" Session Ġaborted ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Session Abort ( reason : ĠString , Ġthrowable : ĠThrowable ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsession Listener ?. on Session Abort ed ( reason , Ġthrowable ) ĊĠĠĠĠĠĠĠ Ġclear Channels ( reason ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclear Channels ( reason : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġpending Regist rations . values . forEach Ġ{ Ġfail Registration ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġpending Regist rations . clear () ĊĠĠĠĠĠĠĠ Ġpending Un regist rations . values . map Ġ{ Ġit . second Ġ}. forEach Ġ{ Ġfail Un registration ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġpending Un regist rations . clear () ĊĠĠĠĠĠĠĠ Ġregist rations . values . forEach Ġ{ Ġfail Registration ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġregist rations . clear () ĊĠĠĠĠĠĠĠ Ġpending Subscriptions . values . forEach Ġ{ Ġfail Subscription ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġpending Subscriptions . clear () ĊĠĠĠĠĠĠĠ Ġpending Un subscriptions . values . map Ġ{ Ġit . second Ġ}. forEach Ġ{ Ġfail Un subscription ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġpending Un subscriptions . clear () ĊĠĠĠĠĠĠĠ Ġsubscriptions . values . forEach Ġ{ Ġfail Subscription ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġsubscriptions . clear () ĊĠĠĠĠĠĠĠ Ġpending Calls . values . forEach Ġ{ Ġfail Call ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġpending Calls . clear () ĊĠĠĠĠĠĠĠ Ġpending Public ations . values . forEach Ġ{ Ġfail Publication ( reason , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġpending Public ations . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġclose WebSocket () Ġ= ĊĠĠĠĠĠĠĠ Ġweb Socket Delegate . close ( WebSocket Close Codes . NORMAL _ CLO S URE , Ġ" Session Ġclosed ") ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend Hello ( realm : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠJOIN ING ĊĠĠĠĠĠĠĠ Ġthis . realm Ġ= Ġrealm ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠMessage . Hello ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrealm , Ġbuild JsonObject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" roles ", Ġbuild JsonObject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" publisher ", Ġempty JsonObject ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" subscriber ", Ġempty JsonObject ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" caller ", Ġempty JsonObject ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" callee ", Ġempty JsonObject ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġsend ( message ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend ( message : ĠMessage ) Ġ{ ĊĠĠĠĠĠĠĠ Ġweb Socket Delegate . send ( message . toJson ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġ< T > ĠSend Channel < T >. send Async ( value : ĠT , Ġclose : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġlaunch Ġa Ġcoroutine Ġfor Ġeach Ġnew Ġvalue Ġso Ġwe 're Ġnot Ġsus pended Ġby Ġconsumers Ġnot Ġreading Ġfrom Ġa Ġchannel ĊĠĠĠĠĠĠĠ Ġ// ĠNote : Ġthis Ġalso Ġmeans Ġthat Ġif Ġcor outines Ġcan Ġstart Ġp iling Ġup , Ġbut Ġbetween Ġdropping Ġmessages Ġand Ġp iling Ġthem Ġup , Ġthe Ġlatter ĊĠĠĠĠĠĠĠ Ġ// Ġis Ġprobably Ġprefer able ĊĠĠĠĠĠĠĠ ĠGlobal Scope . launch ( start Ġ= ĠCor outine Start . UN DISPATCH ED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsend Ġwill Ġfail Ġwhen Ġsomeone Ġcloses Ġthe Ġchannel , Ġwe Ġsw allow Ġthat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( close ) Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdispatch ( trigger : ĠTrigger ) Ġ= Ġmutex . with Lock Ġ{ ĊĠĠĠĠĠĠĠ Ġevaluate ( trigger ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġon Message ( message Json : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġfrom Json To Message ( message Json ) ĊĠĠĠĠĠĠĠ Ġdispatch ( Message Received ( message )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġon Binary Message Received () Ġ{ ĊĠĠĠĠĠĠĠ Ġdispatch ( Binary Message Received ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġon WebSocket Closed ( code : ĠInt , Ġreason : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdispatch ( WebSocket Closed ( code , Ġreason )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġon WebSocket Failed ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdispatch ( WebSocket Failed ( throwable )) ĊĠĠĠ Ġ} Ċ }