Spring WebSocket Portfolio前端实现:AngularJS与WebSocket的实时交互终极指南

Spring WebSocket Portfolio前端实现:AngularJS与WebSocket的实时交互终极指南

【免费下载链接】spring-websocket-portfolio 【免费下载链接】spring-websocket-portfolio 项目地址: https://gitcode.com/gh_mirrors/sp/spring-websocket-portfolio

想要构建实时股票交易系统吗?Spring WebSocket Portfolio项目展示了如何利用AngularJS前端与Spring WebSocket后端实现高效的实时数据交互。这个完整的示例项目为您提供了构建现代实时Web应用的最佳实践。通过STOMP协议和SockJS库,前端能够与服务器建立双向通信,实现股票价格的实时更新和交易操作的即时反馈。

📊 项目概述与核心架构

Spring WebSocket Portfolio是一个完整的股票交易模拟系统,展示了Spring Framework在构建WebSocket应用方面的强大能力。前端使用AngularJS框架,通过STOMP over WebSocket与后端进行实时通信。

项目的主要功能包括:

  • 实时股票价格更新
  • 股票买卖交易功能
  • 用户持仓管理
  • 交易通知和错误处理

🚀 快速启动项目

要开始使用这个项目,您需要先克隆仓库:

git clone https://gitcode.com/gh_mirrors/sp/spring-websocket-portfolio
cd spring-websocket-portfolio

项目支持多种服务器容器,包括Tomcat、Jetty、WildFly和GlassFish。最简单的方式是使用Tomcat:

  1. 设置环境变量 TOMCAT_HOME
  2. 运行部署脚本:
    ./deployTomcat.sh
    
  3. 在浏览器中访问:http://localhost:8080/spring-websocket-portfolio/index.html

🔧 前端架构设计

AngularJS模块结构

前端代码位于 src/main/webapp/ 目录下,主要包含以下关键文件:

核心模块定义

app.js 中,项目定义了AngularJS应用的主模块:

var springPortfolio = angular
    .module('springPortfolio', ['springPortfolio.controllers', 'springPortfolio.services']);

🌐 WebSocket连接管理

STOMP客户端封装

项目在 services.js 中创建了一个 StompClient 工厂,封装了WebSocket连接的核心功能:

.factory('StompClient', ['sockJsProtocols', '$q', function (sockJsProtocols, $q) {
    var stompClient;
    var wrappedSocket = {
        init: function (url) {
            if (sockJsProtocols.length > 0) {
                stompClient = webstomp.over(new SockJS(url, null, {transports: sockJsProtocols}));
            }
            else {
                stompClient = webstomp.over(new SockJS(url));
            }
        },
        connect: function () {
            return $q(function (resolve, reject) {
                if (!stompClient) {
                    reject("STOMP client not created");
                } else {
                    stompClient.connect({}, function (frame) {
                        resolve(frame);
                    }, function (error) {
                        reject("STOMP protocol error " + error);
                    });
                }
            });
        }
    };
    return wrappedSocket;
}])

交易服务实现

TradeService 工厂提供了与后端通信的高级API:

.factory('TradeService', ['StompClient', '$q', function (stompClient, $q) {
    return {
        connect: function (url) {
            stompClient.init(url);
            return stompClient.connect().then(function (frame) {
                return frame.headers['user-name'];
            });
        },
        loadPositions: function() {
            return stompClient.subscribeSingle("/app/positions");
        },
        fetchQuoteStream: function () {
            return stompClient.subscribe("/topic/price.stock.*");
        }
    };
}])

📈 实时数据流处理

股票价格实时更新

controllers.js 中,PortfolioController 控制器处理实时数据流:

var processQuote = function(quote) {
    var existing = $scope.positions[quote.ticker];
    if(existing) {
        existing.change = quote.price - existing.price;
        existing.price = quote.price;
    }
};

tradeService.fetchQuoteStream().then(null, null,
    function(quote) {
        processQuote(quote);
    }
);

持仓更新处理

var udpatePosition = function(position) {
    var existing = $scope.positions[position.ticker];
    if(existing) {
        existing.shares = position.shares;
    }
};

tradeService.fetchPositionUpdateStream().then(null, null,
    function(position) {
        udpatePosition(position);
    }
);

💼 交易功能实现

交易模态框控制器

项目使用AngularUI Bootstrap实现交易模态框:

.controller('TradeModalController',
        ["$scope", "$uibModalInstance", "TradeService", "action", "position",
        function ($scope, $uibModalInstance, tradeService, action, position) {

    $scope.action = action;
    $scope.position = position;
    $scope.numberOfShares = 0;
    $scope.trade = function () {
        $uibModalInstance.close({action: action, position: position, numberOfShares: $scope.numberOfShares});
    };
    $scope.cancel = function () {
        $uibModalInstance.dismiss('cancel');
    };
}])

交易验证逻辑

var validateTrade = function(trade) {
    if (isNaN(trade.shares) || (trade.shares < 1)) {
        $scope.notifications.push("Trade Error: Invalid number of shares");
        return false;
    }
    if ((trade.action === "Sell") && (trade.shares > $scope.positions[trade.ticker].shares)) {
        $scope.notifications.push("Trade Error: Not enough shares");
        return false;
    }
    return true;
}

🎨 用户界面设计

股票表格展示

index.html 中,使用AngularJS的 ng-repeat 指令动态展示股票持仓:

<tr ng-repeat="(ticker, position) in positions">
    <td>{{position.company}}</td>
    <td>{{position.ticker}}</td>
    <td class="number">{{position.price | currency:"$"}}</td>
    <td class="number">
        <span ng-show="position.change > 0" class="glyphicon glyphicon-arrow-up"></span>
        <span ng-show="position.change == 0" class="glyphicon glyphicon-arrow-right"></span>
        <span ng-show="position.change < 0" class="glyphicon glyphicon-arrow-down"></span>
    </td>
    <td class="number">{{position.change | percent:position.price}}</td>
    <td class="number">{{position.shares | number}}</td>
    <td class="number">{{position.price * position.shares | currency:"$"}}</td>
    <td class="trade-buttons">
        <button class="btn btn-primary" ng-click="openTradeModal('buy', position)">Buy</button>
        <button class="btn btn-primary" ng-click="openTradeModal('sell', position)">Sell</button>
    </td>
</tr>

自定义过滤器

项目实现了多个自定义过滤器来格式化数据:

.filter('percent', ['$filter', function ($filter) {
    return function (input, total) {
        return $filter('number')(input / total * 100, 1) + '%';
    };
}])
.filter('totalPortfolioShares', [function () {
    return function (positions) {
        var total = 0;
        for(var ticker in positions) {
            total += positions[ticker].shares;
        }
        return total;
    };
}])

🔌 WebSocket连接配置

SockJS回退策略

项目支持多种传输协议,确保在不同浏览器环境下的兼容性:

.constant('sockJsProtocols', []) // 空数组表示使用所有可用协议

订阅模式

前端通过不同的目的地订阅不同类型的消息:

  • /app/positions - 获取初始持仓数据
  • /topic/price.stock.* - 订阅股票价格更新
  • /user/queue/position-updates - 接收持仓更新
  • /user/queue/errors - 接收错误信息

🛠️ 错误处理与通知

错误流订阅

tradeService.fetchErrorStream().then(null, null,
    function (error) {
        pushNotification(error);
    }
);

通知推送机制

var pushNotification = function(message) {
    $scope.notifications.unshift(message);
};

📱 响应式设计

项目使用Bootstrap和Flat UI实现响应式设计,确保在不同设备上都有良好的用户体验。CSS样式文件位于 static/css/ 目录下:

🚨 最佳实践总结

1. 连接管理

  • 使用工厂模式封装WebSocket连接
  • 支持SockJS回退机制
  • 提供统一的错误处理

2. 数据流处理

  • 使用Promise处理异步操作
  • 分离数据获取和界面更新逻辑
  • 实现实时数据订阅机制

3. 用户界面

  • 使用AngularJS双向数据绑定
  • 实现模块化的控制器设计
  • 提供友好的用户反馈

4. 错误处理

  • 统一的错误通知机制
  • 交易验证逻辑
  • 连接状态管理

🎯 项目优势

  1. 完整的实时交互示例 - 展示了从连接到数据处理的全过程
  2. 生产级代码质量 - 遵循AngularJS最佳实践
  3. 多种服务器支持 - 兼容主流Java Web容器
  4. 完善的错误处理 - 提供完整的异常处理机制
  5. 响应式设计 - 适配不同屏幕尺寸

通过这个项目,您可以学习到如何构建一个完整的实时Web应用前端,掌握AngularJS与WebSocket的集成技巧,为您的下一个实时应用项目打下坚实基础。

📚 深入学习资源

这个Spring WebSocket Portfolio项目为您提供了构建现代实时Web应用的完整前端解决方案,无论是学习还是实际项目开发,都是一个极佳的参考示例。🚀

【免费下载链接】spring-websocket-portfolio 【免费下载链接】spring-websocket-portfolio 项目地址: https://gitcode.com/gh_mirrors/sp/spring-websocket-portfolio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值