Angularjs 中的 Socket.io

Posted

技术标签:

【中文标题】Angularjs 中的 Socket.io【英文标题】:Socket.io in Angularjs 【发布时间】:2017-03-05 01:10:38 【问题描述】:

我将使用 socket.io 在我的 Angular/nodejs 应用程序中添加一些 websockets 功能。

最终目的是在服务器上保留一个“实时”数组,这些数组不可用于编写文档(因为其他人正在编辑它们)。但是我从 socket.io 聊天示例开始,我很快就陷入了困境。 我确定我在这里遗漏了一些微不足道的东西。 $scope.sendMessage() 不发射任何东西..

前面

html

 <input type="text" class="form-control" placeholder="message" name="message" ng-model="message"> <button type="button" ng-click="sendMessage()"> sendMessage </button>

socket.io 被封装在一个服务中

app.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);
                    
                );
            )
        
    ;
);

控制器

$scope.messages=[]
socket.on('init', function (data) 
);
socket.on('send:message', function (message) 
    console.log("send:message")
    $scope.messages.push(message);
);
$scope.sendMessage = function () 
    console.log("send:message")
    socket.emit('send:message',$scope.message);
    $scope.messages.push($scope.message);
;

服务器

var http = require('http');
var server = http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', function (socket) 
  console.log('a user connected');
  socket.on('disconnect', function () 
    console.log('user disconnected');
  );

  socket.on('send:message', function (message) 
    console.log('send:message:'+message);
    socket.broadcast.emit('send:message', 
      text:message
    );
  );
);

【问题讨论】:

服务器肯定应该在“receivemessage”上放置一个处理程序,因为它将接收它,而不是发送它? 在“发射事件”中阅读socket.io/get-started/chat 我不确定我的代码有什么问题 好的,有道理。连接是否正常?它在什么时候停止工作?您是否收到浏览器控制台错误?表达控制台错误? 我在服务器控制台上看到“用户已连接”,但没有别的。我不确定问题是客户端上的emit(send:message) 还是服务器上的处理程序socket.on('send:message')。完全没有错误。 它是否在您发送时写入浏览器控制台? 【参考方案1】:

我已经使用这个堆栈创建了一个小应用程序。查看我的项目here。我在为 AngularJs 制作的 socket-io 周围使用了 this 包装器,发现它非常易于使用!

本质上,在我的项目中,我有以下内容:

NodeJs Server code(入口点):

class Server 
    constructor() 
        this.express = require('express');
        this.redis = require('redis');
        this.client = this.redis.createClient(); //creates a new client
        this.app = this.express();
        this.server = require('http').Server(this.app);
        this.io = require('socket.io').listen(this.server);
        this.app.use('/node_modules', this.express.static(__dirname + '/node_modules'));
        this.app.use('/static', this.express.static(__dirname + '/static'));
        this.app.get('/', (req, res) => 
            res.sendFile(__dirname+'/index.html');
        );

        this.server.listen(8081, '0.0.0.0', () =>  // Listens to port 80
            console.log('Listening on ' + this.server.address().port);
        );
        this.setup();
    

    setup() 
        this.io.on("connection", (socket) => 
            this.socket = socket;
            this.centralServer();
        );
    
    ...
    ...

And then, in index.html,我已经为所需库加载了 JS:

<html lang="en">
<head>
   ...
   ...
    <script src="/node_modules/socket.io-client/dist/socket.io.js" type="text/javascript"></script>
    <script src="/node_modules/redis/index.js" type="text/javascript"></script>
    <script src="/node_modules/angular-socket-io/socket.min.js" type="text/javascript"></script>
    <script src="/static/js/main.js" type="text/javascript"></script>
    ...
    ...
</head>
<body ng-app="app">
    <div ng-include='"static/views/<mainDOM>.html"'></div>
</body>

And finally, in my Angular app,我有以下内容:

var app = angular.module("app", ['btford.socket-io']);
app.controller('myGame', ['$scope', 'socketFactory', function($scope, socketFactory) 
    class Player 
        constructor() 
            this.dom          = $scope;
            this.dom.Room     = ;
            this.socket       = socketFactory();
            this.dom.roomExists   = false;
            this.setup();
        
    ...
    ...
    
    $scope.player = new Player();

我认为我在这个项目中做得很好,提供了一个 AngularJS + Socket-io 的最小示例。

【讨论】:

【参考方案2】:

这确实是您为自己创建的一个复杂问题。我会通过创建一个后端服务(通过 http)来管理锁定。

当用户要求编辑文档时,他们会被授予锁定权限,并且可以进入编辑页面。当他们保存它时,锁被释放。如果另一个用户要求编辑,状态返回告诉他们它已被锁定,并且显示一个错误对话框。

如果用户关闭浏览器或忘记保存,您可能需要对锁定设置某种超时。通过套接字连接管理这些工作量很大,而且难以调试。将一切都保持为简单的 http 请求会容易得多。

【讨论】:

这只是处理正确事件的问题,你不觉得吗?我喜欢 websocket 的想法(实际上我是为了好玩而尝试这种方式。我会立即用 'ping' 间隔制作一个休息资源,但乐趣在哪里?:)) 我什至开始认为没有理由处理这么多事件。客户端应该发出doc:lockdoc:unlock 并处理doc:list。就是这样。 如果你准备好迎接一个很好的挑战,通过一些坚定的努力很有可能使这项工作正常工作 我花了大约 1 个小时,我开始认为这不是我想的那块蛋糕:) 问题是角度路由.. 网络上的 angular/socket.io 中的例子也很少..

以上是关于Angularjs 中的 Socket.io的主要内容,如果未能解决你的问题,请参考以下文章

Angularjs中的$filter

AngularJS中的指令

AngularJS中的transclusion案例

angularjs中的异步操作

AngularJS 中的状态过滤是啥?

angularjs中的filter(过滤器)