AngularJS和Play框架的案例

昨天我们刚刚看完传统架构的事件实现:Java EE 7: EJB 发布 CDI事件通过WebSocket到浏览器客户端,今天介绍一下使用Scala的Play框架和AngularJS这对事件函数语言全新组合:
http://matthiasnehlsen.com/blog/2013/06/23/angularjs-and-play-framework/

架构图如下,聊天案例:


聊天的服务器端协调者Mediator如下:


object ChatApplication extends Controller {

/** Central hub for distributing chat messages */
val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]

/** Controller action serving chat page */
def index = Action { Ok(views.html.index(
"Chat using Server Sent Events")) }

/** Controller action for POSTing chat messages */
def postMessage = Action(parse.json) { req => chatChannel.push(req.body); Ok }

/** Enumeratee for filtering messages based on room */
def filter(room: String) = Enumeratee.filter[JsValue] { json: JsValue => (json \
"room").as[String] == room }

/** Controller action serving activity based on room */
def chatFeed(room: String) = Action { Ok.stream(chatOut &> filter(room) &> EventSource()).as(
"text/event-stream") }

}

这段代码实现了Chat房价分发,如下:


浏览器客户端AngularJS


/** Controllers */
angular.module('sseChat.controllers', ['sseChat.services']).
controller('ChatCtrl', function ($scope, $http, chatModel) {
$scope.rooms = chatModel.getRooms();
$scope.msgs = [];
$scope.inputText =
"";
$scope.user =
"Jane Doe #" + Math.floor((Math.random() * 100) + 1);
$scope.currentRoom = $scope.rooms[0];

/** change current room, restart EventSource connection */
$scope.setCurrentRoom = function (room) {
$scope.currentRoom = room;
$scope.chatFeed.close();
$scope.listen();
};

/** posting chat text to server */
$scope.submitMsg = function () {
$http.post(
"/chat", { text: $scope.inputText, user: $scope.user,
time: (new Date()).toUTCString(), room: $scope.currentRoom.value });
$scope.inputText =
"";
};

/** handle incoming messages: add to messages array */
$scope.addMsg = function (msg) {
$scope.$apply(function () { $scope.msgs.push(JSON.parse(msg.data)); });
};

/** start listening on messages from selected room */
$scope.listen = function () {
$scope.chatFeed = new EventSource(
"/chatFeed/" + $scope.currentRoom.value);
$scope.chatFeed.addEventListener(
"message", $scope.addMsg, false);
};

$scope.listen();
});

Html代码如下:


<div ng-controller="ChatCtrl">
<div id=
"header">
Your Name: <input type=
"text" name="user" id="userField" value="John Doe"
ng-model=
"user" />
<select ng-model=
"currentRoom" ng-change="setCurrentRoom(currentRoom)"
ng-options=
"r.name for r in rooms"></select>
</div>

<div id=
"chat">
<div class=
" msg" ng-repeat="msg in msgs | limitTo:-10"
ng-class=
"msg.user !== user ? 'others' : ''"
data-ng-show=
"hidden == false" data-ng-hide="hidden == true"
data-ng-animate=
"'fadeIn'"><br/>
<strong> says: </strong><br/>
</div>
</div>

<div id=
"footer">
<form ng-submit=
"submitMsg()">
Say something: <input type=
"text" name="chat" id="textField"
ng-model=
"inputText" />
<input type=
"button" id="saySomething" value="Submit"
ng-click=
"submitMsg()" />
</form>
</div>
</div>


[该贴被banq于2013-06-25 09:32修改过]