使用WebSocket调用API

2 投票
1 回答
1984 浏览
提问于 2025-04-18 16:17

我有一个非常简单的应用程序,前端是用 AngularJS 写的,后端是用 Django Rest Framework 写的。我的应用每隔一段时间就会去检查一下API的某个接口,看看有没有新的变化。

这段代码每5秒钟运行一次:

var resource = TokenRestangular.one("jobs", job_id);
resource.then(function (objects) {
    //if we have job completed = true then do something else.                    
},

我知道这种方法有点“老派”。所以我想问,能不能用 websockets 在AngularJS中查找API资源,如果可以的话,应该怎么做呢?

我不想重新写一个新的API,那这个API能同时支持REST连接和通过HTTP的websockets吗?

1 个回答

1

1. 客户端

在你的Angular代码中,写一个服务来连接到一个websocket服务器。使用一个promise,每当收到websocket的数据包时,就更新你应用的$scope。可以这样做:

    myApp.service( 'WSService', function() {
        this.promise = function ($q) {
            // Create a deferred object
            var deferred = $q.defer();
            // Create the WebSocket client pointing to the correct API
            var ws = new WebSocket("ws://myIP:myPort/myAPI");
            // Map the messages to action
            ws.onopen = function()  { console.log( "WSService opened"); };
            ws.onmessage = function (evt) { 
                console.log("onmessage:" + evt);
                deferred.notify(evt);
            };
            ws.onclose = function() { console.log("WSService closed"); };
            // Return the promise
            return deferred.promise;
        }
    });

然后在你的控制器中:

    myApp.controller('MyController', ['$scope','$q','WSService', function($scope, $q, WSService) {
        var promise = WSService.promise($q);

        promise.then(function(evt) { console.log('resolve : ' + evt); }, 
                     function(evt) { console.log('reject : ' + evt); }, 
                     function(evt) {
                         console.log('notify: ' + evt);
                         //Update the scope
                         $scope.myData = evt;
                     }
        );
    }]);

2. 服务器端

在API前面,写一个websocket服务器,它会推送格式合适的JSON数据。例如,你可以在模型的信号(保存、更新)上挂一个函数,这个函数会把你的模型的JSON序列化数据推送给客户端。这样,所有对后端数据库的更新都会立即反映到客户端。

为此,你可以使用一个现成的包,比如django-socketio,这个包看起来很受欢迎。

如果你websocket服务器发送的数据和你的模型及$scope中的数据匹配,那我想可以算作符合REST的标准。

撰写回答