昨天我们刚刚看完传统架构的事件实现: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") }
}
<p class="indent">
|
这段代码实现了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();
});
<p class="indent">
|
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>
<p class="indent">
|
[该贴被banq于2013-06-25 09:33修改过]