Getting angular-socket-io working with Grunt

2019-05-30 10:59发布

I'm having problems to get socket.io working with my project that uses Grunt. I'm currently using angular-socket-io via bower. So here are things that I have done this far:

1) Installed angular-socket-io and socket.io-client via bower

2) Imported following lines exactly into index.html

<script src="bower_components/socket.io-client/socket.io.js"></script>
<script src="bower_components/angular-socket-io/socket.min.js"></script>

3) Added 'btford.socket-io' into my app.js

angular.module('angularApp', [ 'ngCookies', 'ngResource', 'ngSanitize', 'ngRoute', 'ui.bootstrap', 'btford.socket-io'])

4) Made Socket.js file which is

app.factory('Socket', ['socketFactory', '$location',
    function(socketFactory, $location) {
        if($location.host() === "127.0.0.1") {
            return socketFactory({
                prefix: '',
                ioSocket: io.connect($location.protocol() + '://' + $location.host() + ':' + $location.port())
            });
        } else {
            return socketFactory({
                prefix: '',
                ioSocket: io.connect({path: '/node_modules/socket.io'})
            });
        }
    }
]);

Project structure:

Project
|
- node_modules
  |
  - socket.io
- src
  |
  - main
    |
    - webapp
      |
      - app
        |
        - bower_components
        - scripts
          |
          - controllers
          - services
          - app.js
          - Socket.js
        - styles
        - views
        - index.html
- bower.json
- Gruntfile.js
- server.js

But I get following error on every polling:

GET http://127.0.0.1:9000/socket.io/?EIO=3&transport=polling&t=1448635105443-105 404 (Not Found)

What could be wrong? Is it possible to tell angular to import some specific modules of node? I have been searching solution for this from stackoverflow and also Googled it many days, but I haven't found any solution.

However I have found that when it tries to GET socket.io using that address it tries to get it from node_modules path. I have installed there just in case socket.io via npm.

I have also read the instructions of angular-socket-io at Github angular-socket-io

EDIT* I have tried to create server.js which includes following lines:

var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');

app.listen(9000, "127.0.0.1");

function handler (req, res) {
      fs.readFile(__dirname + '/src/main/webapp/app/index.html',
      function (err, data) {
        if (err) {
          res.writeHead(500);
          return res.end('Error loading index.html');
        }

        res.writeHead(200);
        res.end(data);
      });
    }

io.sockets.on('connection', function(socket){
    socket.emit('news', {message: 'hello world'});
    socket.on('my event', function(data){
        console.log(data);
    })
})

But it still say the same thing.

1条回答
萌系小妹纸
2楼-- · 2019-05-30 11:31

Finally I got it working. So here's the answer for anyone who is running Grunt as server using grunt serve or grunt connect.

First do all four steps that are done in question above.

Secondly when you use Grunt to run your server, you need to install and use npm package called grunt-contrib-connect which will have onCreateServer function. This function will allow us to use socket.io with Grunt. This function is included with at least version 0.11.2 of grunt-contrib-connect. You need to load this package in your Gruntfile. If you haven't done so yet, then you can simply add following line to your Gruntfile.js

grunt.loadNpmTasks('grunt-contrib-connect')

Now that you have loaded that npm task you can now use onCreateServer function to use socket.io, like this:

grunt.initConfig({
  connect: {
    server: {
      options: {
        port: 8000,
        hostname: 'localhost',
        onCreateServer: function(server, connect, options) {
          var io = require('socket.io').listen(server);
          // do something with socket
          io.sockets.on('connection', function(socket) {
              io.sockets.on('connection', function(socket) {
                  socket.emit('news', {message: 'hello world'});
                  socket.on('my event', function(data){
                  console.log(data);
                  })
              });
          });
        }
      }
    }
  }
});

Finally you can go to your controller and use your Socket factory you did on client side (in our case it is Socket.js). Here is example of controller:

angular.module('angularApp').controller('MyCtrl', ['$rootScope', '$scope', '$resource', 'Socket', function($rootScope, $scope, $resource, Socket ){
    Socket.on('news', function(data){
        console.log(data);
        Socket.emit('my event', {my: 'data'});
    })
}]);

TIP: If you are using livereload in your server.options then you don't have to worry about it. You can use livereload with socket.io.

查看更多
登录 后发表回答