昨天我们刚刚看完传统架构的事件实现: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修改过]