The chat controller
We will need to create a new controller. This controller will be located at
ReactiveWebStore/app/controllers.
Implementing the chat controller
ChatController.scala should look something like this:
package controllers
import akka.actor.ActorSystem
import akka.stream.Materializer
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.libs.streams._
import actors.ChatUserActor
import actors.ChatBotAdminActor
@Singleton
class ChatController @Inject() (implicit val system: ActorSystem, materializer: Materializer) extends Controller {
import play.api.libs.concurrent.Execution.
Implicits.defaultContext ChatBotAdminActor(system) def index_socket = Action { request =>
Ok(views.html.chat_index()(Flash(Map())))
}
def ws = WebSocket.accept[String, String] { request =>
ActorFlow.actorRef(out => ChatUserActor.props(system)(out))
}
}
The ChatController method will use Google Guice to get injected instances of Actor System and an Actor materializer instance. A materializer is needed because it will provide the instance of the out Actor for each user in the system.
As you can see, we will create an instance of the ChatBotAdmin method passing through the actor system, which Google Guice injected for us. For this controller, we will just have two functions: one function to render the chat UI, and the other one to serve the WebSocket.
The Play framework already provides built-in integration with Akka and WebSockets. So, we will just need to use the ActorFlow method using the actorRef function in order to obtain an out Actor.
Here, we will call the ChatUserActor companion object and create a chat user for the websocket passing out the Actor system the controller has. As you can see, this returns WebSocket.accept, which is a full duplex connection between the web browser and the backend.