Skip to content

Latest commit

 

History

History
164 lines (121 loc) · 4.76 KB

README.md

File metadata and controls

164 lines (121 loc) · 4.76 KB

Vaactor

Use Vaadin Flow with Scala and Akka actors.

Documentation

Detailed documentation can be found in the ScalaDoc of the library.

The project on Github also contains two subprojects with example code.

The example subproject is the example used here in this description.

The demo subproject is a complete chat application with two interfaces - one using session state and one without session state.

How to use it?

Vaactor is implemented in Scala 2.12. You can use it in every Scala project that uses Vaadin and Akka Actors.

Dependencies

Add all needed dependencies (Vaactor, Vaadin and Akka) to your Scala project (using sbt):

resolvers ++= Seq(
  "vaadin-addons" at "http://maven.vaadin.com/vaadin-addons"
)

val vaadinVersion = "10.0.1"
val akkaVersion = "2.5.13"
libraryDependencies ++= Seq(
  "org.vaadin.addons" % "vaactor" % "2.0.0",
  "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
  "com.vaadin" % "vaadin-core" % vaadinVersion,
  "com.typesafe.akka" %% "akka-actor" % akkaVersion
)

Note the "org.vaadin.addons" % "vaactor" % "2.0.0" line - Vaadin directory will deliver the library compiled with scala binary version 2.12 !

Development

Implement a Servlet, an UI Component and a session Actor in your Scala code, and extend them with traits from the vaactor library:

import javax.servlet.annotation.WebServlet

import ExampleObject.globalCnt
import org.vaadin.addons.vaactor._
import com.vaadin.flow.component.button.Button
import com.vaadin.flow.component.html.Label
import com.vaadin.flow.component.orderedlayout.VerticalLayout
import com.vaadin.flow.component.page.Push
import com.vaadin.flow.router.Route
import com.vaadin.flow.server.VaadinServletConfiguration
import com.vaadin.flow.shared.communication.PushMode
import com.vaadin.flow.shared.ui.Transport
import com.vaadin.flow.theme.Theme
import com.vaadin.flow.theme.lumo.Lumo

import akka.actor.Actor.Receive
import akka.actor.{ Actor, Props }


object ExampleObject {
  // global counter
  private[this] var _globalCnt = 0

  def globalCnt: Int = this.synchronized { _globalCnt }

  def globalCnt_=(value: Int): Unit = this.synchronized { _globalCnt = value }

}

@WebServlet(urlPatterns = Array("/*"), asyncSupported = true)
@VaadinServletConfiguration(productionMode = false)
class ExampleServlet extends VaactorSessionServlet {

  override val sessionProps: Props = Props(classOf[ExampleSessionActor])

}

@Route("")
@Theme(value = classOf[Lumo], variant = Lumo.DARK)
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET)
class ExampleUI extends VerticalLayout with Vaactor.HasActor with Vaactor.HasSession {

  // counter local to this UI
  var uiCnt = 0

  val stateDisplay = new Label()

  setMargin(true)
  setSpacing(true)
  add(new Label("Vaactor Example"))
  add(
    new Button("Click Me", { _ =>
      uiCnt += 1
      session ! s"Thanks for clicking! (uiCnt:$uiCnt)"
    })
  )
  add(stateDisplay)
  add(
    new Button("Show Counts") with Vaactor.HasActor {
      addClickListener(_ => session ! VaactorSession.RequestSessionState)

      override def receive: Receive = {
        case state: Int => setText(s"Show Counts - uiCnt is $uiCnt, sessionCnt is $state, globalCnt is $globalCnt")
      }
    }
  )

  override def receive: Receive = {
    case hello: String =>
      globalCnt += 1
      stateDisplay.setText(s"$hello (globalCnt:$globalCnt)")
  }

}

class ExampleSessionActor extends Actor with VaactorSession[Int] {
  // state is session counter
  override val initialSessionState = 0

  override val sessionBehaviour: Receive = {
    case msg: String =>
      sessionState += 1
      sender ! s"$msg (sessionCnt:$sessionState)"
  }

}

Deployment

Vaactor applications are deployed as servlets. During development you could use xsb-web-plugin.

addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.0.2")

The actual default version of jetty in the plugin has problems with Vaadin 10.0 and websockets, so you should use the specific jetty version configured below.

containerLibs in Jetty := Seq("org.eclipse.jetty" % "jetty-runner" % "9.3.21.v20170918" intransitive())

enablePlugins(JettyPlugin)

If you use the xsbt-web-plugin, start a web server sbt jetty:start and your Vaactor application should be available at http://localhost:8080:

License

Vaactor is licensed under the Apache 2.0 License.