将socket.io集成到angularjs项目中

时间:2014-07-28 20:24:07

标签: javascript node.js angularjs socket.io

我正在尝试将socket.io添加到我的angularjs项目中。我的参考是http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/?redirect_from_locale=zh#disqus_thread。我试图修改它如下:

关于socket.io服务器: app.js:

var express = require('express');
var app = module.exports = express();

var server = require('http').createServer(app);

// Hook Socket.io into Express
var io = require('socket.io').listen(server);

// Socket.io Communication

var socket = require('./scripts/socket.js');
io.sockets.on('connection', socket);

// Start server at http://127.0.0.1:3000

server.listen(3000, function() {
console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env);
});

脚本/ socket.js:

// Keep track of which names are used so that there are no duplicates
var userNames = (function () {
  var names = {};

  var claim = function (name) {
    if (!name || names[name]) {
      return false;
    } else {
      names[name] = true;
      return true;
    }
  };

  // find the lowest unused "guest" name and claim it
  var getGuestName = function () {
    var name,
      nextUserId = 1;

    do {
      name = 'Guest ' + nextUserId;
      nextUserId += 1;
    } while (!claim(name));

    return name;
  };

  // serialize claimed names as an array
  var get = function () {
    var res = [];
    for (user in names) {
      res.push(user);
    }

    return res;
  };

  var free = function (name) {
    if (names[name]) {
      delete names[name];
    }
  };

  return {
    claim: claim,
    free: free,
    get: get,
    getGuestName: getGuestName
  };
}());

// export function for listening to the socket
module.exports = function (socket) {
  var name = userNames.getGuestName();

  // send the new user their name and a list of users
  socket.emit('init', {
    name: name,
    users: userNames.get()
  });

  // notify other clients that a new user has joined
  socket.broadcast.emit('user:join', {
    name: name
  });

  // broadcast a user's message to other users
  socket.on('send:message', function (data) {
    socket.broadcast.emit('send:message', {
      user: name,
      text: data.message
    });
  });

  // validate a user's name change, and broadcast it on success
  socket.on('change:name', function (data, fn) {
    if (userNames.claim(data.name)) {
      var oldName = name;
      userNames.free(oldName);

      name = data.name;

      socket.broadcast.emit('change:name', {
        oldName: oldName,
        newName: name
      });

      fn(true);
    } else {
      fn(false);
    }
  });

  // clean up when a user leaves, and broadcast it to other users
  socket.on('disconnect', function () {
    socket.broadcast.emit('user:left', {
      name: name
    });
    userNames.free(name);
  });
};

这些是socket.io的所有文件。 在节点app.js之后,它显示“Express server在端口3000上侦听开发模式”


从角度种子修改角度部分:https://github.com/angular/angular-seed 的index.html:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <meta charset="UTF-8">
  <title>Angular Socket.io IM Demo App</title>
  <link rel="stylesheet" href="css/app.css"></head>
<body>
  <h1>Angular Socket.io IM Demo App</h1>
  <div ng-controller="AppCtrl">
    <div class="col">
      <h3>Messages</h3>
      <div class="overflowable">
        <p ng-repeat="message in messages" ng-class="{alert: message.user == 'chatroom'}">: </p>
      </div>
    </div>
    <div class="col">
      <h3>Users</h3>
      <div class="overflowable">
        <p ng-repeat="user in users"></p>
      </div>
    </div>
    <div class="clr">
      <form ng-submit="sendMessage()">
        Message:
        <input size="60" ng-model="message">
        <input type="submit" value="Send"></form>
    </div>
    <div class="clr">
      <h3>Change your name</h3>
      <p>Your current user name is </p>
      <form ng-submit="changeName()">
        <input ng-model="newName">
        <input type="submit" value="Change Name"></form>
    </div>
  </div>
  <script src="lib/angular/angular.js"></script>
  <script src="/socket.io/socket.io.js"></script>
  <script src="js/app.js"></script>
  <script src="js/services.js"></script>
  <script src="js/controllers.js"></script>
  <script src="js/filters.js"></script>
  <script src="js/directives.js"></script>
</body>
</html>

JS / app.js:

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']);       

JS / services.js:

angular.module('myApp.services', [])
.value('version', '0.1')
.factory('socket', 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);
                    }
                });
            })
        }
    };
});

JS / controllers.js:

/* Controllers */

function AppCtrl($scope, socket) {

  // Socket listeners
  // ================
  socket.on('init', function (data) {
    $scope.name = data.name;
    $scope.users = data.users;
  });

  socket.on('send:message', function (message) {
    $scope.messages.push(message);
  });

  socket.on('change:name', function (data) {
    changeName(data.oldName, data.newName);
  });

  socket.on('user:join', function (data) {
    $scope.messages.push({
      user: 'chatroom',
      text: 'User ' + data.name + ' has joined.'
    });
    $scope.users.push(data.name);
  });

  // add a message to the conversation when a user disconnects or leaves the room
  socket.on('user:left', function (data) {
    $scope.messages.push({
      user: 'chatroom',
      text: 'User ' + data.name + ' has left.'
    });
    var i, user;
    for (i = 0; i < $scope.users.length; i++) {
      user = $scope.users[i];
      if (user === data.name) {
        $scope.users.splice(i, 1);
        break;
      }
    }
  });

  // Private helpers
  // ===============

  var changeName = function (oldName, newName) {
    // rename user in list of users
    var i;
    for (i = 0; i < $scope.users.length; i++) {
      if ($scope.users[i] === oldName) {
        $scope.users[i] = newName;
      }
    }

    $scope.messages.push({
      user: 'chatroom',
      text: 'User ' + oldName + ' is now known as ' + newName + '.'
    });
  }

  // Methods published to the scope
  // ==============================

  $scope.changeName = function () {
    socket.emit('change:name', {
      name: $scope.newName
    }, function (result) {
      if (!result) {
        alert('There was an error changing your name');
      } else {

        changeName($scope.name, $scope.newName);

        $scope.name = $scope.newName;
        $scope.newName = '';
      }
    });
  };

  $scope.messages = [];

  $scope.sendMessage = function () {
    socket.emit('send:message', {
      message: $scope.message
    });

    // add the message to our model locally
    $scope.messages.push({
      user: $scope.name,
      text: $scope.message
    });

    // clear message box
    $scope.message = '';
  };
}

然后我在localhost:8000中运行angularjs。在网页中,我似乎可以发送一些导致凉亭更新的内容:

[Mon, 28 Jul 2014 20:10:13 GMT] "GET /app/lib/angular/angular.js" "Mozilla/5.0 (
Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.1
53 Safari/537.36"
[Mon, 28 Jul 2014 20:10:13 GMT] "GET /socket.io/socket.io.js" "Mozilla/5.0 (Wind
ows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 S
afari/537.36"

然而,在localhost:3000上运行的socket.io什么都没有收到。

我想我必须在angularjs和socket.io之间的连接中出错,例如

<script src="/socket.io/socket.io.js"></script> 
index.html中的

var socket = io.connect(); 

在js / services.js中。

我试图将它们改为

<script src="http://127.0.0.1:3000/socket.io/socket.io.js"></script>

<script src="http://localhost:3000/socket.io/socket.io.js"></script>

var socket = io.connect('http://127.0.0.1:3000');

var socket = io.connect('http://localhost:3000');

var socket = io.connect('http://localhost');

但没有任何作用。也许我的方式完全错误。

所以我复制粘贴我的代码,希望有人可以帮助我。任何帮助或建议都将不胜感激。

更新 现在看来客户端可以连接到服务器,但无法正确加载控制器。不知道如何解决它。

1 个答案:

答案 0 :(得分:1)

终于在一整天后找出了上述代码的错误。

1.客户端应通过添加显式IP来连接socket.io服务器,即:

在services.js中:

var socket = io.connect("http://127.0.0.1:3000");
index.html中的

<script src="http://127.0.0.1:3000/socket.io/socket.io.js"></script>  

2.注意angular-seed文件夹中没有路径和文件lib / angular / angular.js。需要手动创建文件夹并添加文件。

3.问题中的代码没有正确显示数据。

这是我修复了所有错误的代码,它可以顺利运行。 https://github.com/shaosh/angular-socketio-chatroom-example