This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//This shows an updated websocket example for play2.2.0 utilizing Concurrent.broadcast vs Enumerator.imperative, which | |
// is now deprecated. | |
object Application extends Controller { | |
def index = WebSocket.using[String] { request => | |
//Concurernt.broadcast returns (Enumerator, Concurrent.Channel) | |
val (out,channel) = Concurrent.broadcast[String] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create the Global class in your /app folder root package: | |
import play.api.{GlobalSettings, Play} | |
import play.api.Play.current | |
import play.api.mvc._ | |
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits.global | |
/** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[1] def fitSenatorsBasedOnRarity(committeesWithIssueConfs: Map[Committee, mutable.Queue[String]], senators: Set[Senator], party: String) = | |
{ | |
[2] var takenSenators: mutable.Set[Senator] = senators.to[mutable.Set] | |
[3] committeesWithIssueConfs.foreach(committee => | |
committee._2.foreach(issue => { | |
// get a senator from each faction | |
[4] val tmpSenatorDem = takenSenators.find(s => s.faction.name.equalsIgnoreCase(party) && doesMatchPositionRule(issue, s)) | |
[5] tmpSenatorDem match { | |
case None => // do nothing | |
case Some(senator) => { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[1] def defineSenatorTrack() = | |
{ | |
// for every committee | |
[2] committeeIssueSenatorMap.foreach( committee => { | |
committee._2.foreach(issueConf => { | |
issueConf._2.foreach( senator => { | |
[3] val max = committee._2.foldLeft(0)( (result, current) => result + current._2.filter(_.faction.name.equalsIgnoreCase(senator.faction.name)).size) / 2 | |
// does the senator fit in subcommittee 1 | |
[4] if(doesSenatorFitInSubCommittee(senator.faction.name, max, senator, committee._1.name,SUBCOMMITTEE_1_KEY)) { | |
// add |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This trait allows websocket classes to push messages to client via a concurrent channel */ | |
trait WebSocketChannel | |
{ | |
//instantiate an Enumerator and Channel | |
val (out,channel) = Concurrent.broadcast[JsValue] | |
// method to allow pushing of data up the channel | |
def push(data: JsValue) = channel.push(data) | |
def cleanSocketResources() = channel.end() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This trait allows websocket classes to push messages to client via a concurrent channel */ | |
trait WebSocketChannel | |
{ | |
//instantiate an Enumerator and Channel | |
val (out,channel) = Concurrent.broadcast[JsValue] | |
// method to allow pushing of data up the channel | |
def push(data: JsValue) = channel.push(data) | |
def cleanSocketResources() = channel.end() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// define our events | |
case class RegisterSocket() | |
case class Connected(out: Enumerator[JsValue], ref: ActorRef) | |
class WSClientVisitor(name: String) extends Actor with ActorLogging with WebSocketChannel | |
{ | |
def receive = { | |
case RegisterSocket => { | |
// close over sender | |
val myClient = sender |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Application extends Controller { | |
/* Each WebSocket connection state is managed by an Agent actor. | |
A new actor is created for each WebSocket, and is killed when the socket is closed. | |
For each play actor agent, a unique WebSocket Client Worker actor is created to process WS events via the WSManager Actor. | |
*/ | |
def websocketManager(deviceId: String) = WebSocket.async[JsValue] | |
{ | |
request => | |
// instantiate an actor to hold web socket |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait MockWebSocketChannel extends WebSocketChannel | |
{ | |
var mockWebSocketChannelQueue : List[JsValue] = List.empty | |
override def push(data: JsValue): Unit = mockWebSocketChannelQueue = mockWebSocketChannelQueue :+ data | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WSClientVisitorSpec extends TestKit(_system = Akka.system(FakeApplication())) with WordSpecLike with Matchers with ImplicitSender | |
{ | |
//instantiate test constants | |
val actorRef = TestActorRef(new WSClientVisitor("TEST") with MockWebSocketChannel, name= "test") | |
// get a test reference to our actor | |
val actor = actorRef.underlyingActor | |
"Web Socket Client For Visitor" should { | |
"register a new socket" in new WithApplication(app = FakeApplication(additionalConfiguration =Map("akka.event-handlers" -> List("akka.testkit.TestEventListener")), | |
withGlobal = Some(new GlobalSettings() { |
OlderNewer