我正在使用Node.js創建媒體上傳微服務。該服務通過將上傳的二進制數據接收到緩衝區,然後使用S3 npm軟件包上載到S3存儲桶來工作。我試圖使用該包中的eventEmitter來顯示上傳到S3的數據量,並將其發送回正在上傳的客戶端(以便他們可以看到上傳進度)。我使用socket.io發送進度數據給客戶端。Socket.io無法將數據發送到客戶端的獨特空間
我遇到的問題是,socket.io中的.emit事件會將上載進度數據發送給所有連接的客戶端,而不僅僅是發起上傳的客戶端。據我所知,一個套接字連接到'連接'上的默認房間,它由客戶端的'id'鏡像。根據官方文檔,使用socket.to(id).emit()應該將數據範圍僅發送給該客戶端,但這不適用於我。
更新了例代碼:
server.js:
var http = require('http'),
users = require('./data'),
app = require('./app')(users);
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
var io = require('./socket.js').listen(server);
socket.js:
var socketio = require('socket.io');
var socketConnection = exports = module.exports = {};
socketConnection.listen = function listen(app) {
io = socketio.listen(app);
exports.sockets = io.sockets;
io.sockets.on('connection', function (socket) {
socket.join(socket.id);
socket.on('disconnect', function(){
console.log("device "+socket.id+" disconnected");
});
socketConnection.upload = function upload (data) {
socket.to(socket.id).emit('progress', {progress:(data.progressAmount/data.progressTotal)*100});
};
});
return io;
};
s3upload.js:
var config = require('../config/aws.json');
var s3 = require('s3');
var path = require('path');
var fs = require('fs');
var Busboy = require('busboy');
var inspect = require('util').inspect;
var io = require('../socket.js');
...
var S3Upload = exports = module.exports = {};
....
S3Upload.upload = function upload(params) {
// start uploading to uploader
var uploader = client.uploadFile(params);
uploader.on('error', function(err) {
console.error("There was a problem uploading the file to bucket, either the params are incorrect or there is an issue with the connection: ", err.stack);
res.json({responseHTML: "<span>There was a problem uploading the file to bucket, either the params are incorrect or there is an issue with the connection. Please refresh and try again.</span>"});
throw new Error(err);
}),
uploader.on('progress', function() {
io.upload(uploader);
}),
uploader.on('end', function(){
S3Upload.deleteFile(params.localFile);
});
};
當使用DEBUG = *節點myapp.js,我看到了socket.io-pa RSER取入該信息,但它不是它發射到客戶端:
socket.io-parser encoding packet {"type":2,"data":["progress",{"progress":95.79422221709825}],"nsp":"/"} +0ms
socket.io-parser encoded {"type":2,"data":["progress",{"progress":95.79422221709825}],"nsp":"/"} as 2["progress",{"progress":95.79422221709825}] +0ms
然而,如果刪除該代碼的。要部分,它發送數據到客戶端(儘管到所有客戶,這將不利於在所有):
io.sockets.on('connection', function(socket) {
socket.join(socket.id);
socket.emit('progress', {progress: (data.progressAmount/data.progressTotal)*100});
});
DEBUG = *節點myapp.js:
socket.io:client writing packet {"type":2,"data":["progress",{"progress":99.93823786632886}],"nsp":"/"} +1ms
socket.io-parser encoding packet {"type":2,"data":["progress",{"progress":99.93823786632886}],"nsp":"/"} +1ms
socket.io-parser encoded {"type":2,"data":["progress",{"progress":99.93823786632886}],"nsp":"/"} as 2["progress",{"progress":99.93823786632886}] +0ms
engine:socket sending packet "message" (2["progress",{"progress":99.93823786632886}]) +0ms
engine:socket flushing buffer to transport +0ms
engine:ws writing "42["progress",{"progress":99.84186540937002}]" +0ms
engine:ws writing "42["progress",{"progress":99.93823786632886}]" +0ms
我在做什麼錯在這裏?有沒有不同的方式將事件從服務器發送到我只缺少特定的客戶端?
我編輯了我的問題以顯示更多底層代碼體系結構。我不能簡單地發送連接,因爲我將來自另一個路由的信息傳遞給套接字。 –
我已經根據你的代碼編輯了我的答案,我在同一個文件中合併了'socket.js'和's3upload.js',以使它更容易。如果你真的需要保持它們分開,我建議你切換具有導入S3的socket.js的依賴項,而不是反過來。您將需要基於套接字事件調用函數,以便它需要訪問's3upload.js'函數。 –
我會嘗試用您的建議重新構建我的應用程序,感謝您的幫助。根據你的建議移動我的代碼的相關問題:是否真的,使用套接字時,應該真的圍繞着socket.io設計,以便所有的邏輯都通過套接字處理程序傳遞?如果這是真的,那麼使用套接字時不會使專用路由無法寫入? –