在角度工厂上使用套接字

Posted

技术标签:

【中文标题】在角度工厂上使用套接字【英文标题】:using socket on angular factory 【发布时间】:2016-04-07 10:01:25 【问题描述】:

我试图使用角度服务从我的节点 js 服务器传递到我的视图 json 对象。 我调试了服务函数,发现它确实在获取对象,但是当我返回对象数组时,我得到了 $scope.messages = undefined。

我的服务器代码:

var express = require("express");
var url = require("url");
var app = express(); // express.createServer();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
server.listen(8080);
app.use(express.static(__dirname + '/public'));
var MongoClient = require('mongodb').MongoClient
, format = require('util').format;

var insertMsg, Collection;
var socketMap = ;

MongoClient.connect('mongodb://127.0.0.1:27017/EladGuy', function(err, db) 
    if(err) 
        throw err;
    Collection = db.collection('messages');
    console.log("connected to DB");
);

app.get("/*", function(request, response) 
    var screen = url.parse(request.url).pathname;
    check = String(screen).split("=");
    check2 = String(screen).split("/");
    if (check[0] != "/screen" && check2[1] != "html") 
        response.sendFile(__dirname + '/public/index.html');
     else 
        if (check[1]>0 && check[1]<4) 
            saveScreen = check[1];
            response.sendFile(__dirname + '/public/oldIndex.html');
         else if (check2[1] == "html") 
            response.sendFile(__dirname + screen);
         else 
            response.sendFile(__dirname + '/public/index.html');
        
    
);

io.sockets.on('connection', function(socket) 
    socket.on('sendId', function(stationId) 
        socketMap[parseInt(stationId)] = socket;
    );
    socket.on('getMessages', function(unUsed) 
        res = [];
        Collection.find("screensId":'$eq': parseInt(saveScreen)).toArray(function(err, docs) 
            docs.forEach(function(doc) 
                res.push(doc);
            );
            socket.emit('sendMessages', res);
        );
    );
    socket.on('getAllMessages',function(unUsed)
        res = [];
        Collection.find().toArray(function(err, docs) 
            docs.forEach(function(doc) 
                res.push(doc);
            );
            console.log("STAM CHECK:" + res[0].name);
            socket.emit('sendAllMessages', res);
        );
    );
);

main.js 代码(用于轮换、服务和控制器):

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config(function($routeProvider) 
    $routeProvider
        .when('/',
            
                controller: 'HomeController',
                templateUrl: 'menu.html'
            )
        .when('/stations',
            
                controller: 'StationsController',
                templateUrl: 'messagesView.html'
            )
        .when('/',
            
                controller: 'HomeController',
                templateUrl: 'menu.html'
            )
        .otherwise(redirectTo: '/');
);
 var customersService = function ($http, $q) 
        var addsFactory = ;
        var socket = io.connect('http://localhost:8080');
        addsFactory.getMessages = function () 
            socket.emit('getAllMessages',null);
            socket.on('sendAllMessages',function (result) 
                return result;
            );
        ;
        return addsFactory;
 ;
  myApp.factory('customersService', ['$http', '$q', customersService]);


myApp.controller('StationsController',function($scope,customersService)
    $scope.messages = [];
    $scope.messages = customersService.getMessages();
);

myApp.controller('HomeController',function($scope)
    $scope.message="Loaded Menu!!";
);

有人可以帮我了解我的问题吗?

【问题讨论】:

getMessages() 没有返回任何内容。来自内部函数的 return 不会返回到外部函数,因此 return result 什么也不做 那么我怎样才能从匿名函数返回一些东西到外部函数呢? 可以将匿名函数替换为作为参数传入的回调。需要使用$apply 来告诉 Angular 也运行摘要 你能给我写一个例子吗? 谷歌搜索“angular socket”会发现很多工厂和教程。重要的是要了解在角核心之外更改范围需要使用$apply 【参考方案1】:

您将addsFactory.getMessages 封装在变量customersService 中。然后在一个外部函数中,您尝试使用customersService.getMessages(); 调用它。您定义它的方式是customersService 本身就是一个函数,其中有一个addsFactory 对象和一个函数getMessages。你能看到你的函数调用与那个不匹配吗?有各种方法可以解决这个问题。您需要在外部范围内定义此函数:

function getMessages(socket) 
    socket.emit('getAllMessages',null);
    socket.on('sendAllMessages',function (result) 
        return result;
    );
;

这样你就可以将getMessages 函数暴露给你的控制器,并给它一个socket 参数。然后你可以通过getMessages(io.connect('http://localhost:8080'); 调用它并将返回的值传递给你想要的任何东西。您应该阅读一些角度最佳实践。我推荐John Papa's style guide。

【讨论】:

不要认为你对工厂函数的解释正确 你说得对,我没有注意到他实际上将customersService 定义为工厂,但他得到未定义值的原因仍然是他没有正确引用addsFactory.getMessages 函数。他可以保留工厂功能,但随后他需要以将getMessages 暴露给控制器的方式对其进行重写。据我所知,将该函数放在对象中 (addsFactory) 没有任何意义,注入 $http$q

以上是关于在角度工厂上使用套接字的主要内容,如果未能解决你的问题,请参考以下文章

无法从角度连接 laravel 网络套接字

2-5:套接字(Socket)编程之从内核角度深入理解套接字

我如何以扭曲的工厂方法访问redis?

如何在角度应用程序中嵌入 Web 套接字的证书

SSLSocket

无法从 Data Fusion 连接 Cloud SQL mySql 实例。异常“无法创建套接字工厂 'com.google.cloud.sql.mysql.SocketFactory”