/* Ċ Ġ* ĠJ aval in Ġ- Ġhttps :// jav al in . io Ċ Ġ* ĠCopyright Ġ 2 0 1 7 ĠDavid ĠÃ ħ se Ċ Ġ* ĠLicensed Ġunder ĠApache Ġ 2 . 0 : Ġhttps :// github . com / tip sy / jav al in / blob / master / LICENSE Ċ Ġ*/ Ċ Ċ package Ġio . jav al in . websocket Ċ Ċ import Ġio . jav al in . core . Path Parser Ċ import Ġorg . eclipse . jetty . websocket . api . Session Ċ import Ġorg . eclipse . jetty . websocket . api . Upgrade Request Ċ import Ġorg . eclipse . jetty . websocket . api . annotations .* Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ Ċ data Ġclass ĠW s Entry ( val Ġpath : ĠString , Ġval Ġhandler : ĠW s Handler , Ġval Ġcase Sensitive Urls : ĠBoolean ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġpath Parser Ġ= ĠPath Parser ( path , Ġcase Sensitive Urls ) ĊĠĠĠ Ġfun Ġmatches ( request Uri : ĠString ) Ġ= Ġpath Parser . matches ( request Uri ) ĊĠĠĠ Ġfun Ġextract Path Params ( request Uri : ĠString ) Ġ= Ġpath Parser . extract Path Params ( request Uri ) Ċ } Ċ Ċ /** Ċ Ġ* ĠEvery ĠWebSocket Ġrequest Ġpasses Ġthrough Ġa Ġsingle Ġinstance Ġof Ġthis Ġclass . Ċ Ġ* ĠSession ĠIDs Ġare Ġgenerated Ġand Ġtracked Ġhere , Ġand Ġpath - parameters Ġare Ġcached Ġfor Ġperformance . Ċ Ġ*/ Ċ @ WebSocket Ċ class ĠW s Path Matcher Ġ{ ĊĊĠĠĠ Ġval Ġws Entries Ġ= Ġmutable ListOf < Ws Entry >() ĊĠĠĠ Ġprivate Ġval Ġsession Ids Ġ= ĠConcurrent HashMap < Session , ĠString >() ĊĠĠĠ Ġprivate Ġval Ġsession Path Params Ġ= ĠConcurrent HashMap < Session , ĠMap < String , ĠString >>() ĊĊĠĠĠ Ġfun Ġadd ( ws Entry : ĠW s Entry ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! ws Entry . case Sensitive Urls Ġ&& Ġws Entry . path Ġ!= Ġws Entry . path . toLowerCase ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" By Ġdefault ĠURLs Ġmust Ġbe Ġlowercase . ĠChange Ġc asing Ġor Ġcall Ġ` app . enable Case Sensitive Urls ()` Ġto Ġallow Ġmixed Ġc asing .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġws Entries . add ( ws Entry ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On WebSocket Connect ĊĠĠĠ Ġfun Ġweb Socket Connect ( session : ĠSession ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfind Entry ( session )?. let Ġ{ Ġit . handler . connect Handler ?. handle ( wrap ( session , Ġit )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On WebSocket Message ĊĠĠĠ Ġfun Ġweb Socket Message ( session : ĠSession , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfind Entry ( session )?. let Ġ{ Ġit . handler . message Handler ?. handle ( wrap ( session , Ġit ), Ġmessage ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On WebSocket Message ĊĠĠĠ Ġfun Ġweb Socket Binary Message ( session : ĠSession , Ġbuffer : ĠByteArray , Ġoffset : ĠInt , Ġlength : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfind Entry ( session )?. let Ġ{ Ġit . handler . binary MessageHandler ?. handle ( wrap ( session , Ġit ), Ġbuffer . to Typed Array (), Ġoffset , Ġlength ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On WebSocket Error ĊĠĠĠ Ġfun Ġweb Socket Error ( session : ĠSession , Ġthrowable : ĠThrowable ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġfind Entry ( session )?. let Ġ{ Ġit . handler . error Handler ?. handle ( wrap ( session , Ġit ), Ġthrowable ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ On WebSocket Close ĊĠĠĠ Ġfun Ġweb Socket Close ( session : ĠSession , ĠstatusCode : ĠInt , Ġreason : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġfind Entry ( session )?. let Ġ{ Ġit . handler . close Handler ?. handle ( wrap ( session , Ġit ), ĠstatusCode , Ġreason ) Ġ} ĊĠĠĠĠĠĠĠ Ġdestroy ( session ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Entry ( session : ĠSession ) Ġ= Ġfind Entry ( session . upgrade Request ) ĊĊĠĠĠ Ġfun Ġfind Entry ( req : ĠUpgrade Request ) Ġ= Ġws Entries . find Ġ{ Ġit . matches ( req . request URI . path ) Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrap ( session : ĠSession , Ġws Entry : ĠW s Entry ): ĠW s Session Ġ{ ĊĠĠĠĠĠĠĠ Ġsession Ids . put If Absent ( session , ĠUUID . randomUUID (). toString ()) ĊĠĠĠĠĠĠĠ Ġsession Path Params . put If Absent ( session , Ġws Entry . extract Path Params ( session . upgrade Request . request URI . path )) ĊĠĠĠĠĠĠĠ Ġreturn ĠW s Session ( session Ids [ session ] !! , Ġsession , Ġsession Path Params [ session ] !! , Ġws Entry . path ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdestroy ( session : ĠSession ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsession Ids . remove ( session ) ĊĠĠĠĠĠĠĠ Ġsession Path Params . remove ( session ) ĊĠĠĠ Ġ} Ċ Ċ } Ċ