package Ġorg . h ild an . k ross bow . st omp Ċ Ċ import Ġkotlinx . coroutines . Cancellation Exception Ċ import Ġkotlinx . coroutines . Coroutine Name Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Experimental Cor outines Api Ċ import Ġkotlinx . coroutines . Flow Preview Ċ import Ġkotlinx . coroutines . Job Ċ import Ġkotlinx . coroutines . cancel Ċ import Ġkotlinx . coroutines . channels . Broadcast Channel Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . flow .* Ċ import Ġkotlinx . coroutines . launch Ċ import Ġorg . h ild an . k ross bow . st omp . config . Heart Beat Ċ import Ġorg . h ild an . k ross bow . st omp . config . Sto mp Config Ċ import Ġorg . h ild an . k ross bow . st omp . frame . Frame Body Ċ import Ġorg . h ild an . k ross bow . st omp . frame . Sto mp Decoder Ċ import Ġorg . h ild an . k ross bow . st omp . frame . Sto mp Frame Ċ import Ġorg . h ild an . k ross bow . st omp . frame . encode ToBytes Ċ import Ġorg . h ild an . k ross bow . st omp . frame . encode ToText Ċ import Ġorg . h ild an . k ross bow . st omp . heart beats .* Ċ import Ġorg . h ild an . k ross bow . st omp . heart beats . Heart Be ater Ċ import Ġorg . h ild an . k ross bow . st omp . heart beats . is Heart Beat Ċ import Ġorg . h ild an . k ross bow . st omp . heart beats . send Heart Beat Ċ import Ġorg . h ild an . k ross bow . websocket . WebSocket Close Codes Ċ import Ġorg . h ild an . k ross bow . websocket . WebSocket Frame Ċ import Ġorg . h ild an . k ross bow . websocket . WebSocket Connection Ċ import Ġkotlin . coroutines . Coroutine Context Ċ import Ġkotlin . coroutines . Empty Coroutine Context Ċ Ċ /** Ċ Ġ* ĠA Ġweb Ġsocket Ġwrapper Ġthat Ġenables Ġsending Ġand Ġreceiving ĠSTO MP Ġframes Ġthrough Ġthe Ġsocket . Ċ Ġ* ĠIt Ġhandles Ġthe Ġframe Ġconversions Ġbetween Ġweb Ġsockets Ġand ĠSTO MP . Ċ Ġ* ĠIt Ġmanages Ġheart Ġbe ats Ġand Ġis Ġaware Ġof Ġheart Ġbeat Ġframes . Ċ Ġ*/ Ċ @ Opt In ( Experimental Cor outines Api :: class , ĠFlow Preview :: class ) Ċ internal Ġclass ĠSto mp Socket ( ĊĠĠĠ Ġprivate Ġval Ġweb Socket Connection : ĠWebSocket Connection , ĊĠĠĠ Ġprivate Ġval Ġconfig : ĠSto mp Config , ĊĠĠĠ Ġcoroutine Context : ĠCor outine Context Ġ= ĠEmpty Coroutine Context Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġscope Ġ= ĠCor outine Scope ( coroutine Context Ġ+ ĠJob () Ġ+ ĠCor outine Name (" st omp - socket ")) ĊĊĠĠĠ Ġprivate Ġvar Ġheart Be ater : ĠHeart Be ater ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Broadcast Channel ] Ġof Ġdecoded ĠSTO MP Ġframes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġst omp Frames Channel Ġ= ĠBroadcast Channel < Sto mp Frame >( Channel . BUFFER ED ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Flow ] Ġof Ġdecoded ĠSTO MP Ġframes . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠMultiple Ġconcurrent Ġcollect ors Ġare Ġallowed Ġand Ġcorrespond Ġto Ġindependent Ġsubscriptions . ĊĠĠĠĠ Ġ* ĠAll Ġframes Ġare Ġsent Ġto Ġall Ġsubscribers Ġsimilar ly Ġto Ġa Ġ[ Broadcast Channel ]. ĊĠĠĠĠ Ġ* ĠC ancellation Ġof Ġone Ġcollector Ġresults Ġin Ġthe Ġcancellation Ġof Ġthe Ġcorresponding Ġsubscription Ġbut Ġdoesn 't Ġfail ĊĠĠĠĠ Ġ* Ġthe Ġothers . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġst omp Frames Flow : ĠFlow < Sto mp Frame > Ġ= Ġst omp Frames Channel . as Flow () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġscope . launch ( Coroutine Name (" st omp - frame - decoder ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb Socket Connection . incoming Frames . consume As Flow () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. catch Ġ{ Ġprocess Upstream Websocket Exception ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Each Ġ{ Ġprocess WebSocket Frame ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. catch Ġ{ Ġclose ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġprocess Upstream Websocket Exception ( ex : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠUp stream Ġ( websocket ) Ġerrors Ġshould Ġjust Ġpropagate Ġthrough Ġthe ĠSTO MP Ġframes Ġchannel . ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġshouldn 't Ġcall ĠSto mp Socket . close () Ġbecause Ġthe Ġsocket Ġis Ġmost Ġlikely Ġalready Ġclosed / failed . ĊĠĠĠĠĠĠĠ Ġst omp Frames Channel . close ( ex ) ĊĠĠĠĠĠĠĠ Ġconfig . instrumentation ?. on WebSocket Client Error ( ex ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġprocess WebSocket Frame ( ws Frame : ĠWebSocket Frame ) Ġ{ ĊĠĠĠĠĠĠĠ Ġheart Be ater ?. notify Msg Received () ĊĠĠĠĠĠĠĠ Ġconfig . instrumentation ?. on WebSocket Frame Received ( ws Frame ) ĊĠĠĠĠĠĠĠ Ġif Ġ( ws Frame . is Heart Beat ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ// Ġnot Ġan Ġactual ĠSTO MP Ġframe ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġf Ġ= Ġdecode Frame ( ws Frame ) Ġ?: Ġreturn Ġ// Ġping / p ong Ġframe ĊĠĠĠĠĠĠĠ Ġconfig . instrumentation ?. on Frame Decoded ( ws Frame , Ġf ) ĊĠĠĠĠĠĠĠ Ġif Ġ( f Ġis ĠSto mp Frame . Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠSto mp Error Frame Received ( f ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( f Ġis ĠSto mp Frame . Connected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Heart Be ats ( f . headers . heart Beat ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġst omp Frames Channel . send ( f ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdecode Frame ( f : ĠWebSocket Frame ): ĠSto mp Frame ? Ġ= Ġwhen Ġ( f ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Frame . Text Ġ-> ĠSto mp Decoder . decode ( f . text ) ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Frame . Binary Ġ-> ĠSto mp Decoder . decode ( f . bytes ) ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Frame . Ping , Ġis ĠWebSocket Frame . P ong Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġis ĠWebSocket Frame . Close Ġ-> Ġthrow ĠWebSocket Closed Unexpected ly ( f . code , Ġf . reason ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit Heart Be ats ( server Heart Beat : ĠHeart Beat ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġneg oti ated Heart Beat Ġ= Ġconfig . heart Beat . neg oti ated ( server Heart Beat ) ĊĠĠĠĠĠĠĠ Ġif Ġ( neg oti ated Heart Beat Ġ== ĠNO _ HE ART _ BE ATS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġheart Be ater Ġ= ĠHeart Be ater ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġheart Beat Ġ= Ġneg oti ated Heart Beat , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtolerance Ġ= Ġconfig . heart Beat Tolerance , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Heart Beat Ġ= Ġ{ Ġweb Socket Connection . send Heart Beat () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Missing Heart Beat Ġ= Ġ{ Ġclose ( Missing Heart Beat Exception ( neg oti ated Heart Beat . expected Period Millis )) Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġheart Be ater ?. start In ( scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġsend Sto mp Frame ( frame : ĠSto mp Frame ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( frame . body Ġis ĠFrame Body . Binary ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb Socket Connection . send Binary ( frame . encode ToBytes ()) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFrame s Ġwithout Ġbody Ġare Ġalso Ġsent Ġas Ġtext Ġbecause Ġthe Ġheaders Ġare Ġalways Ġtext ual . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAlso , Ġsome Ġsock JS Ġimplementations Ġdon 't Ġsupport Ġbinary Ġframes . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb Socket Connection . send Text ( frame . encode ToText ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġheart Be ater ?. notify Msg Sent () ĊĠĠĠĠĠĠĠ Ġconfig . instrumentation ?. on Sto mp Frame Sent ( frame ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġclose ( cause : ĠThrowable ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġare Ġshut ting Ġdown Ġbecause Ġof ĠWebSocket Closed Unexpected ly , Ġthen Ġwe Ġshouldn 't Ġtry Ġto Ġclose Ġthe Ġweb ĊĠĠĠĠĠĠĠ Ġ// Ġsocket Ġagain . ĊĠĠĠĠĠĠĠ Ġ// ĠIn Ġcase Ġof ĠSTO MP ĠERROR Ġframe , Ġthe Ġserver Ġmust Ġclose Ġthe Ġconnection . ĊĠĠĠĠĠĠĠ Ġ// ĠHowever , Ġthe Ġweb Ġsocket Ġdid Ġnot Ġerror Ġand Ġwe Ġmay Ġneed Ġto Ġclose Ġthe Ġoutput , Ġso Ġwe Ġdon 't Ġdis crimin ate ĊĠĠĠĠĠĠĠ Ġ// Ġagainst ĠSto mp Error Frame Received , Ġand Ġclose Ġanyway Ġeven Ġin Ġthis Ġcase . ĊĠĠĠĠĠĠĠ Ġif Ġ( cause Ġ! is ĠWebSocket Closed Unexpected ly ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb Socket Connection . close ( code Ġ= Ġclose Code For ( cause ), Ġreason Ġ= Ġcause ?. message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġthis Ġis Ġreported Ġeven Ġif Ġthe Ġwebsocket Ġwas Ġclosed Ġunexpected ly Ġ( it Ġdoesn 't Ġhave Ġto Ġbe Ġus Ġclosing Ġit ) ĊĠĠĠĠĠĠĠ Ġconfig . instrumentation ?. on WebSocket Closed ( cause ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠRequired Ġto Ġstop Ġthe Ġsubscribers Ġof Ġthe Ġframes , Ġand Ġpropagate Ġthe Ġexception Ġif Ġpresent . ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġclose Ġthis Ġchannel Ġafter Ġthe Ġweb Ġsocket , Ġso Ġthat Ġconsumers Ġcan Ġsee Ġthey Ġcan 't Ġsend ĠUNS UB SCR IBE . ĊĠĠĠĠĠĠĠ Ġst omp Frames Channel . close ( cause ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠCancel s Ġthe Ġcollection Ġof Ġweb Ġsocket Ġframes . ĊĠĠĠĠĠĠĠ Ġ// ĠMaybe Ġthis Ġwill Ġhappen Ġbefore Ġthe Ġweb Ġsocket Ġserver 's Ġclose Ġframe Ġis Ġreceived , Ġbut Ġit 's ĠOK Ġbecause Ġwe ĊĠĠĠĠĠĠĠ Ġ// Ġclosed Ġthe Ġst omp Frames Channel Ġalready . ĊĠĠĠĠĠĠĠ Ġscope . cancel ( Cancellation Exception ( cause ?. message , Ġcause )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclose Code For ( cause : ĠThrowable ?): ĠInt Ġ= Ġwhen Ġ( cause ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnull Ġ-> ĠWebSocket Close Codes . NORMAL _ CLO S URE ĊĠĠĠĠĠĠĠ Ġis ĠMissing Heart Beat Exception Ġ-> Ġ 3 0 0 2 Ġ// Ġ 1 0 0 2 Ġwould Ġbe ĠPROTO COL _ ERROR , Ġbut Ġbrowsers Ġreserve Ġit ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 3 0 0 1 Ġ// Ġ 1 0 0 1 Ġwould Ġbe ĠGO ING _ AW AY , Ġbut Ġbrowsers Ġreserve Ġthis Ġcode Ġfor Ġactual Ġpage Ġleave ĊĠĠĠ Ġ} Ċ } Ċ