package Ġnet . join u . pro dig y Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġmu . Kotlin Logging Ċ import Ġjava . net . Inet SocketAddress Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġkotlin . coroutines . coroutine Context ĊĊ Ċ /** Ċ Ġ* ĠThe Ġclass Ġthat Ġis Ġused Ġto Ġactually Ġrun Ġprotocols Ċ Ġ* Ċ Ġ* Ġ@ param Ġnetwork Provider Ġ[ Network Provider ] Ġ- Ġsome Ġentity Ġthat Ġis Ġresponsible Ġfor Ġsending Ġand Ġreceiving Ġpackets Ċ Ġ*/ Ċ class ĠProtocol Runner ( val Ġnetwork Provider : ĠNetwork Provider ) Ġ{ ĊĠĠĠ Ġval Ġprotocols Ġ= ĠConcurrent HashMap < String , ĠAbstract Protocol >() ĊĠĠĠ Ġval Ġresponses Ġ= ĠConcurrent HashMap < Long , ĠProtocol Packet >() ĊĊĠĠĠ Ġprivate Ġval Ġsend Handler : ĠSend Handler Ġ= Ġ{ Ġpacket , Ġto Ġ-> Ġnetwork Provider . send ( packet , Ġto ) Ġ} ĊĠĠĠ Ġprivate Ġval Ġreceive Handler : ĠReceive Handler Ġ= Ġ{ Ġthread Id Ġ-> ĊĠĠĠĠĠĠĠ Ġvar Ġresponse Packet : ĠProtocol Packet ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( coroutine Context . isActive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Packet Ġ= Ġresponses . remove ( thread Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response Packet Ġ!= Ġnull ) Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġresponse Packet !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger (" Protocol Runner -${ Random (). nextInt () }") ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġhandler Ġto Ġhandler Ġrunner Ġcontext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġprotocol Ġ[ Abstract Protocol ] Ġ- Ġprotocol Ġto Ġadd ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Protocol ( protocol : ĠAbstract Protocol ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprotocols [ protocol . handler . protocol Name ] Ġ= Ġprotocol ĊĊĠĠĠĠĠĠĠ Ġprotocol . apply Send Handler ( send Handler ) ĊĠĠĠĠĠĠĠ Ġprotocol . handler . apply Send Handler ( send Handler ) ĊĊĠĠĠĠĠĠĠ Ġprotocol . apply Receive Handler ( receive Handler ) ĊĠĠĠĠĠĠĠ Ġprotocol . handler . apply Receive Handler ( receive Handler ) ĊĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Protocol Ġ${ protocol . handler . protocol Name } Ġregistered " Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠBind s Ġ[ Network Provider ] Ġto Ġsome Ġaddress ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġon Ġ[ Inet SocketAddress ] Ġ- Ġaddress Ġto Ġbind ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġbind ( on : ĠInet SocketAddress ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Bound Ġto : Ġ$ on " Ġ} ĊĊĠĠĠĠĠĠĠ Ġnetwork Provider . bind ( on ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRuns Ġ[ Network Provider ] Ġand Ġhandles Ġpacket Ġtransmission Ġand Ġdispatch ing ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġrun Sus pending () Ġ= Ġcoroutine Scope Ġ{ ĊĠĠĠĠĠĠĠ Ġlaunch Ġ{ Ġnetwork Provider . run Sus pending () Ġ} ĊĊĠĠĠĠĠĠĠ Ġsupervisor Scope Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( coroutine Context . isActive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( packet , Ġfrom ) Ġ= Ġnetwork Provider . receive () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( packet . protocol Flag Ġ== ĠProtocol Packet Flag . RESPONSE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponses [ packet . protocol Thread Id ] Ġ= Ġpacket ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Received Ġresponse Ġ[ protocol Name : Ġ${ packet . protocol Name }, Ġmessage Type : Ġ${ packet . message Type }, Ġrecipient : Ġ$ from , Ġthread Id : Ġ${ packet . protocol Thread Id }] " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprotocol Ġ= Ġprotocols [ packet . protocol Name ] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( protocol Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Received Ġa Ġmessage Ġfor Ġunknown Ġhandler : Ġ${ packet . protocol Name }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandler Ġ= Ġprotocol . handler . handlers [ packet . message Type ] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( handler Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Received Ġa Ġmessage Ġfor Ġunknown Ġmessage Type : Ġ${ packet . message Type } Ġfor Ġhandler : Ġ${ packet . protocol Name }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . request Ġ= ĠRequest ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpacket . payload , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpacket . protocol Thread Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpacket . message Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpacket . protocol Name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Handler ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Received ĠREQUEST Ġpacket Ġfor Ġthread Id : Ġ${ packet . protocol Thread Id }, Ġinvoking Ġhandler ..." Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . body . invoke ( handler ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCloses Ġ[ Network Provider ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Closed " Ġ} ĊĊĠĠĠĠĠĠĠ Ġnetwork Provider . close () ĊĠĠĠ Ġ} Ċ } Ċ