AngularJS和Play框架的案例

13-06-25 banq
                   

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

这段代码实现了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>

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>

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

                   

1