【问题标题】:io connection event is not fired second timeio 连接事件不会第二次触发
【发布时间】:2016-10-27 10:28:01
【问题描述】:

chokidar 模块的帮助下,我正在创建一个文件夹监视程序。我的 Server.js 代码是:

let express = require('express')
let app = express();
let http = require('http').Server(app);
let path = require('path');
let chokidar = require('chokidar');
let io = require('socket.io')(http);

let port = process.env.port || 1337;

let clientPath = path.join(__dirname, 'client');

app.use(express.static(clientPath));

app.get('/', function (req, res) {
    res.sendFile(path.join(clientPath, 'HTML1.html'));
});

http.listen(port, function () {
    console.log(`listning on ${port}`);
});

let watcher = chokidar.watch(path.join(clientPath, 'images'),
    { ignored: /^\./, persistent: true }
);

watcher
    .on('add', function (path) {
        console.log('File', path, 'has been added');
        io.sockets.on('connection', function (socket) {
            socket.emit('imageAddClient', { imagePath: path });
            socket.on('imageAddServer', function (data) {
                console.log(`${data.imagePath} has been processed at client`);
            });
        });
    })
    .on('change', function (path) {
        console.log('File', path, 'has been changed');
    })
    .on('unlink', function (path) {
        console.log('File', path, 'has been removed');
    })
    .on('error', function (error) {
        console.error('Error happened', error);
    });

在客户端,我创建了 angular factory,以便在添加图像后自动加载页面。我的客户代码是:

var app = angular.module('imageLoaderApp', []);
app.controller('loadController', function ($scope, socket) {
    try {
        images = [];
        socket.on('imageAddClient', function (data) {
            let fileName = data.imagePath.substring(data.imagePath.lastIndexOf('\\') + 1);
            console.log(fileName);
            images.push({ name: fileName, src: fileName });
            socket.emit('imageAddServer', { imagePath: fileName });
        });

        $scope.images = images;
        //console.log($scope.images);
    }
    catch (exception) {
        console.log(`Error from loadController ${exception}`);
    }
});

app.factory('socket', function ($rootScope) {
    var socket = io.connect('http://localhost:1337');
    return {
        on: function (eventName, callBack) {
            socket.on(eventName, function () {
                let args = arguments;
                $rootScope.$apply(function () {
                    callBack.apply(socket, args);
                });
            });
        },
        emit: function (eventName, data, callBack) {
            socket.emit(eventName, data);
        }
    }
});

但是,来自 io 的“连接”事件仅在一次我启动服务器时触发。后记如果我在文件夹中添加一个图像文件,我可以看到 watcher 事件被触发但 'connection' 事件没有被触发

我做错了什么?

【问题讨论】:

    标签: javascript angularjs node.js socket.io


    【解决方案1】:

    您需要在观察者之外声明 io.on('connection') 。您需要在启动时分配它,以便它知道何时连接了套接字。

    var io = require('socket.io')(http);
    
    io.on('connection', function(socket) {
    	console.log('Socket connected!');
    
    	socket.on('imageAddServer', function(data) {
    		console.log('image has been processed at the client')
    	});
    	socket.on('disconnect', function() {
    		console.log('Socket disconnected');
    	});
    });
    
    watcher
        .on('add', function (path) {
            console.log('File', path, 'has been added');
    		io.emit('imageAddClient', { imagePath: path }); //send it to the client sockets that are connected
        });

    将此代码用作更新代码的参考。

    【讨论】:

    • 这样,每次加载页面时它都会断开客户端,而无需创建新连接或维护连接。
    【解决方案2】:

    其实Murf 让我走上了正轨。我只是改变了他的顺序。我把答案放在这里,以防将来有人需要它...... 所以 watcher 和 io 的代码是这样的:

    io.on('connection', function (socket) {
        executeWatcher(socket);
        socket.on('imageAddServer', function (data) {
            console.log(`${data.imagePath} has been processed at client`);
        });
        socket.on('disconnect', function () {
            console.log('Client disconnected');
        });
    
    });
    
    let executeWatcher = function (socket) {
        watcher
            .on('add', function (path) {
                console.log('File', path, 'has been added');
                socket.emit('imageAddClient', { imagePath: path });
            })
            .on('change', function (path) {
                console.log('File', path, 'has been changed');
            })
            .on('unlink', function (path) {
                console.log('File', path, 'has been removed');
            })
            .on('error', function (error) {
                console.error('Error happened', error);
            });
    }
    

    【讨论】:

    • 你在使用 babel 吗?
    • @HermLuna,没有。我通常用 Typescript 编写代码。很长一段时间后,我在JS中编写了上面的代码。有什么特别的要求吗?
    • 没有。我只看到模板文字。所以,如果你使用的是 babel。利用 es5 和 es6 的新特性。干得好!
    猜你喜欢
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 2013-08-20
    • 2021-11-27
    • 1970-01-01
    相关资源
    最近更新 更多