I have a Play Framework based WebSocket connection defined as below:
def socket(chargingStationId: String, isPersistentConn: Boolean): WebSocket = WebSocket.acceptOrResult[JsValue, JsValue] { request =>
Future.successful {
val supportedProtocols = bindings.appConfig.ocppServerCfg.supportedProtocols
val acceptedProtocolExistsInReq = acceptedSubProtocol(request.headers, supportedProtocols)
if (acceptedProtocolExistsInReq) {
Right(ActorFlow.actorRef { actorRef =>
Props(new OCPPActor(actorRef, chargingStationId, isPersistentConn))
})
} else {
logger.warn(s"Supported Protocol is not one of ${supportedProtocols.mkString(",")} " +
"in the Sec-WebSocket-Protocol header")
Left(BadRequest)
}
}
}
I have my routes.conf that has the end-point to access this WebSocket, now I need to know how I can get an instance of the Websocket so that I can use it to send messages? For example., I have my server where I expose these WebSocket connection needs to use the already open connection with the specific client to send some messages at a later point in time for example., from my service layer. My service layer however does not know which connections are open. So how can I create a cache of open connections that I can use as a look up and send messages if one exist?
This idea comes to my mind where I have a WebSocket manager that can store ActorRef's like this:
object WebSocketManager {
private var connections: Set[ActorRef] = Set.empty
def addConnection(connection: ActorRef): Unit = {
connections += connection
}
def removeConnection(connection: ActorRef): Unit = {
connections -= connection
}
def broadcast(message: JsValue): Unit = {
connections.foreach(_ ! message)
}
}
Is something like that a good idea? My server code then could then do a look up using the ActorRef and send the messages. What do you think?