2015-02-10 3 views
0

В настоящее время я пытаюсь реализовать контент в реальном времени с socket.io и angular.js, и, насколько я понимаю, я все сделал правильно, но в реальном времени не работает. Возможно, я пропустил что-то важное.Угловой + сокет не работает?

Я напишу сценарий того, как он должен работать. В основном пользователь пишет контент, а затем публикует значение на сервере. В home.html содержимое должно быть в режиме реального времени (я поставил все ниже, включая home.html).

Вот код

server.js

var express  = require('express'); 
var app   = express(); 
var morgan  = require('morgan'); 
var mongoose = require('mongoose'); 
var bodyParser = require('body-parser'); 
var path  = require('path'); 
var config  = require('./config'); 

// REAL TIME WORK 
var http  = require('http').Server(app); 
var io   = require('socket.io')(http); 

app.use(bodyParser.urlencoded({ extended: true })); 
app.use(bodyParser.json()); 

app.use(function(req, res, next) { 
    res.setHeader('Access-Control-Allow-Origin', '*'); 
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); 
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization'); 
    next(); 
}); 

// log our request to our terminal 
app.use(morgan('dev')); 

// Connect to our database using mongoose 
mongoose.connect(config.database, function(err) { 
    if(err) { 
     console.log("Connection to a mongodb database has failed"); 
    } else { 
     console.log("Connected to a database"); 
    } 
}); 


// set our static files to a designated location 
app.use(express.static(__dirname + '/public')); 

var apiRouter = require('./app/routes/api') (app, express, io); 
app.use('/api', apiRouter); 

// registered before your api routes. 
app.get('*', function(req, res) { 
    res.sendFile(path.join(__dirname + '/public/app/views/index.html')); 
}); 

http.listen(config.port, function(err) { 
    if(err) { 
     console.log("There's an error connecting the app to port" + config.port); 
    } else { 
     console.log("App is listening on port " + config.port); 
    } 
}); 

api.js

module.exports = function(app, express, io) { 

    // creating our first router 
    var apiRouter = express.Router(); 

    // signup a user 
    var createStory = function(req, res) { 

     var story = new Story({ 
      user: req.decoded.id, 
      content: req.body.content 
     }); 

     story.save(function(err) { 

      if(err) { 
       res.send(err); 
       return; 
      } 

      io.emit('story', req.body.content); 
      res.json({ message: 'Story has been created!'}); 

     }); 
    }; 

    apiRouter.route('/') 

     .post(createStory) 


     .get(function(req, res) { 

      Story.find({ user: req.decoded.id }, function(err, story) { 
       if(err) { 
        res.send(err); 
        return; 
       } 

       res.json(story); 
      }); 


     }); 

service.js

angular.module('storyService', []) 


.factory('Story', function($http, $window) { 

    // get all approach 
    var storyFactory = {}; 

    var generateReq = function(method, url, data) { 
      var req = { 
       method: method, 
       url: url, 
       headers: { 
       'x-access-token': $window.localStorage.getItem('token') 
       }, 
       cache: false 
      } 

      if(method === 'POST') { 
       req.data = data; 
      } 
      return req; 
     }; 

    storyFactory.all = function() { 
     return $http(generateReq('GET', '/api/')); 
    }; 


    storyFactory.create = function(storyData) { 
     return $http(generateReq('POST', '/api/', storyData)); 
    }; 

    storyFactory.getSingleStory = function(user_name, story_id) { 
     return $http(generateReq('GET', '/api/' + user_name + '/' + story_id)); 
    }; 

    storyFactory.allStories = function() { 
     return $http(generateReq('GET', '/api/all_stories')); 
    }; 

    return storyFactory; 

}) 


.factory('socketio', ['$rootScope', function ($rootScope) { 

     var socket = io.connect(); 
     return { 
      on: function (eventName, callback) { 
       socket.on(eventName, function() { 
        var args = arguments; 
        $rootScope.$apply(function() { 
         callback.apply(socket, args); 
        }); 
       }); 
      }, 
      emit: function (eventName, data, callback) { 
       socket.emit(eventName, data, function() { 
        var args = arguments; 
        $rootScope.$apply(function() { 
         if (callback) { 
          callback.apply(socket, args); 
         } 
        }); 
       }); 
      } 
     }; 
    }]); 

controller.js

angular.module('storyCtrl', ['storyService']) 


.controller('StoryController', function(Story, $routeParams, $scope, socketio) { 

    var vm = this; 

    Story.all() 
    .success(function(data) { 
     $scope.stories = data; 
    }); 


    Story.getSingleStory($routeParams.user_name, $routeParams.story_id) 
    .success(function(data) { 
     $scope.storyData = data; 
    }); 

    vm.createStory = function() { 


     vm.message = ''; 

     Story.create(vm.storyData) 
     .success(function(data) { 


       // clear the form 
       vm.storyData = {} 
       vm.message = data.message; 

       socketio.on('story', function() { 
        $scope.stories.push(data); 
       }); 

      }); 
    }; 

}); 

index.html

<!DOCTYPE html> 

<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>User Diary</title> 


    <base href="/"> 

    <!-- CSS --> 
    <!-- load bootstrap from CDN and custom CSS --> 
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.1/paper/bootstrap.min.css"> 

    <!-- load angular and angular-route via CDN --> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.js"></script> 

    <script src="/socket.io/socket.io.js"></script> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.js"></script> 

    <!-- directives --> 



    <!--controllers --> 

    <script src="app/controllers/storyCtrl.js"></script> 
    <script src="app/services/storyService.js"></script> 


    <!-- main Angular app files --> 
    <script src="app/app.routes.js"></script> 
    <script src="app/app.js"></script> 


</head> 


<body ng-app="userApp"> 


<main class="container"> 

    <!-- ANGULAR VIEWS --> 
    <div ng-view></div> 
</main> 



</body> 
</html> 

home.html

<div class="panel-body" ng-repeat="story in stories | reverse" > 
    <ul class="list-group"> 
     <li class="list-group-item"> 
      <div class="row"> 
       <div class="col-xs-10 col-md-11"> 
        <div> 
         <div class="mic-info"> 
          {{ story.createdAt | date:'MMM d, yyyy' }} 
         </div> 
        </div> 
        <div class="comment-text"> 
         <h4>{{ story.content }}</h4> 
        </div> 
       </div> 
      </div> 
     </li> 
    </ul> 
</div> 

Я знаю, что его огромный, причина, почему я отправляю все это потому, что я не хочу, чтобы пропустить на что угодно.

Я действительно новым для всего этого Socket.io + angular.js, если у вас есть какие-либо мнения, которые могли бы научить меня кое-что о Socket.io + angular.js, что означало бы много для меня :)

+0

В вас r StoryController вы регистрируете прослушиватель событий каждый раз при создании нового сообщения, вы должны сделать это один раз (плюс он будет зарегистрирован после первого испускания на сервере). Также контроллер, похоже, использует сочетание синтаксиса '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' – noj

+0

Спасибо, что ответили, но не могли бы вы рассказать об этом в качестве ответа, чтобы я мог его принять, и я все еще путаюсь, что делать прямо сейчас. – airsoftFreak

+0

Я прокомментировал, так как не уверен, устранит проблему. Первое, что я имел в виду, это то, что вам нужно только зарегистрировать прослушиватель событий 'socketio.on ('story', function (content) {//})' один раз, не каждый раз, когда вы создаете новую историю.Во-вторых, если вы используете синтаксис 'controllerAs', тогда вы должны назначить' this' или 'vm' в вашем случае, а не' $ scope' – noj

ответ

2

Следуя за комментариями.

  1. Слушатель событий socketio.on(..) необходимо создать только один раз. Он будет получать все будущие события до его удаления. Также не следует смешивать vm и $scope

    angular.module('storyCtrl', ['storyService']) 
    
    
    .controller('StoryController', function(Story, $routeParams, socketio) { 
    
        var vm = this; 
        vm.stories = []; 
    
        Story.all() 
        .success(function(data) { 
         vm.stories = data; 
        }); 
    
    
        Story.getSingleStory($routeParams.user_name, $routeParams.story_id) 
        .success(function(data) { 
         vm.storyData = data; 
        }); 
    
        vm.createStory = function() { 
         vm.message = ''; 
    
         Story.create(vm.storyData) 
         .success(function(data) { 
          // clear the form 
          vm.storyData = {} 
          vm.message = data.message; 
         }); 
        }; 
    
        socketio.on('story', function (data) { 
         vm.stories.push(data); 
        }); 
    }); 
    

    Создание контроллера как ng-controller="StoryController as StoryCtrl" и повторить с ng-repeat="story in StoryCtrl.stories"

  2. вашей стороне сервера испускают реагирует только с содержимым сообщения, когда кажется, он должен возвращать объект, по крайней мере, content и createdAt свойства

    // signup a user 
    var createStory = function(req, res) { 
    
        var story = new Story({ 
         user: req.decoded.id, 
         content: req.body.content 
        }); 
    
        story.save(function(err) { 
    
         if(err) { 
          res.send(err); 
          return; 
         } 
    
         io.emit('story', { 
          user: req.decoded.id, 
          createdAt: new Date(), 
          content: req.body.content 
         }); 
    
         // you might be able to do instead 
         // io.emit('story', story.toObject()) 
    
         res.json({ message: 'Story has been created!'}); 
    
        }); 
    }; 
    
+0

он работает, но после третьей попытки данные в режиме реального времени перестают быть очень странными. Если вы заходите на свою учетную запись и пытаетесь отправить данные и переходите на маршрут/allStories, то в реальном времени не отображается Еще раз спасибо – airsoftFreak

+0

Я имею в виду попытку открыть 2 браузера, 1 инкогнито и обычный браузер – airsoftFreak

+0

Я не могу проверить, код на вашем героку не изменился – noj

Смежные вопросы