2015-11-18 3 views
6

मैं मीडिया अपलोड माइक्रोस्कोस बनाने के लिए नोड.जेएस का उपयोग कर रहा हूं। यह सेवा अपलोड के बाइनरी डेटा को एक बफर में ले कर काम करती है, और फिर S3 बाल्टी पर अपलोड करने के लिए S3 npm पैकेज का उपयोग करके काम करती है। मैं उस पैकेज में मौजूद ईवेंट एमिटर का उपयोग करने की कोशिश कर रहा हूं जो एस 3 पर अपलोड किए गए डेटा की मात्रा दिखाता है, और उस क्लाइंट को वापस भेजता है जो अपलोड कर रहा है (ताकि वे अपलोड प्रगति देख सकें)। मैं क्लाइंट को प्रगति डेटा भेजने के लिए socket.io का उपयोग कर रहा हूं।सॉकेट.यो क्लाइंट के अद्वितीय कमरे में डेटा उत्सर्जित करने में असमर्थ

मेरी समस्या यह है कि socket.io में .emit ईवेंट अपलोड किए गए क्लाइंट को न केवल क्लाइंट को अपलोड किए गए क्लाइंट को अपलोड प्रगति डेटा भेज देगा। जैसा कि मैं इसे समझता हूं, एक सॉकेट 'कनेक्शन' पर एक डिफ़ॉल्ट कमरे से जुड़ती है, जिसे क्लाइंट साइड पर 'आईडी' द्वारा प्रतिबिंबित किया जाता है। आधिकारिक दस्तावेज़ों के मुताबिक, socket.to (id) .emit() का उपयोग केवल उस क्लाइंट को स्कॉप्ड डेटा भेजना चाहिए, लेकिन यह मेरे लिए काम नहीं कर रहा है।

UPDATED उदाहरण कोड:

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); 
}); 
}; 

डीबग का उपयोग करते समय = * नोड 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 

हालांकि, अगर मैं इस कोड की करें.अभियान हिस्से को हटाने, यह ग्राहक के लिए डेटा (सभी ग्राहकों के लिए यद्यपि भेजता है,

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 

क्या मैं गलत कर रहा हूँ यहाँ: जिस पर सभी की मदद नहीं करेगा):

io.sockets.on('connection', function(socket) { 
    socket.join(socket.id); 
    socket.emit('progress', {progress: (data.progressAmount/data.progressTotal)*100}); 
}); 

डीबग = * नोड myapp.js? क्या सर्वर से ईवेंट को उत्सर्जित करने का एक अलग तरीका है केवल विशिष्ट क्लाइंट जो मुझे याद आ रही है?

उत्तर

3

आपके द्वारा पोस्ट किए गए कोड का दूसरा उदाहरण काम करना चाहिए और यदि ऐसा नहीं होता है, तो आपको अधिक कोड पोस्ट करना चाहिए।

मैं यह समझ के रूप में, एक सॉकेट 'कनेक्शन' पर एक डिफ़ॉल्ट कमरा है, जो ग्राहक के पक्ष 'आईडी' से नजर आता है को जोड़ता है। आधिकारिक दस्तावेज़ों के अनुसार, socket.to (id) .emit() का उपयोग करके डेटा केवल उस क्लाइंट को स्कॉप्ड किया जाना चाहिए, लेकिन यह मेरे लिए काम नहीं कर रहा है।

सॉकेट.ओओ उससे कहीं अधिक आसान है। नीचे दिया गया कोड प्रत्येक क्लाइंट को 'हैलो' संदेश भेजेगा जब वे कनेक्ट हों:

io.sockets.on('connection', function (socket) { 
    socket.emit('hello'); 
}); 

हर बार एक नया ग्राहक सॉकेट से कनेक्ट होता है।आईओ सर्वर, यह उस विशेष सॉकेट का उपयोग पैरामीटर के रूप में निर्दिष्ट कॉलबैक चलाएगा। socket.id उस सॉकेट की पहचान करने के लिए सिर्फ एक अनूठा कोड है, लेकिन आपको वास्तव में किसी भी चीज़ के लिए उस चर की आवश्यकता नहीं है, ऊपर दिया गया कोड आपको एक विशेष socket के माध्यम से एक संदेश भेजने का तरीका दिखाता है।

Socket.io भी आप बनाना नामस्थान/कमरे कुछ कार्यों प्रदान करता है ताकि आप कर सकते हैं कुछ पहचानकर्ता (रूम का नाम) के तहत समूह कनेक्शन और उन सभी को संदेश प्रसारित करने में सक्षम हो:

io.sockets.on('connection', function (socket) { 
    // This will be triggered after the client does socket.emit('join','myRoom') 
    socket.on('join', function (room) { 
     socket.join(room); // Now this socket will receive all the messages broadcast to 'myRoom' 
    }); 
... 

अब आप चाहिए socket.join(socket.id) समझें कि यह समझ में नहीं आता है क्योंकि कोई सॉकेट सॉकेट आईडी साझा नहीं करेगा। कि सब कुछ उपरोक्त कोड में

socketConnection.upload = function upload (data) { 
     socket.to(socket.id).emit('progress', {progress:(data.progressAmount/data.progressTotal)*100}); 
    }; 

नोट अंदर io.sockets.on('connection',function (socket) { हर बार एक ग्राहकों कनेक्ट चलाया जाएगा: नए कोड के साथ इस सवाल का जवाब

संपादित करने के लिए:

आप दो समस्याओं यहाँ है, सबसे पहले सर्वर के लिए। आप नवीनतम उपयोगकर्ता की सॉकेट पर इंगित करने के लिए फ़ंक्शन को ओवरराइट कर रहे हैं।

दूसरी समस्या यह है कि आप सॉकेट और एस 3 संचालन को जोड़ नहीं रहे हैं। एक ही फाइल में socket.js और 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.io'); 

var socketConnection = exports = module.exports = {}; 
var S3Upload = exports = module.exports = {}; 

io = socketio.listen(app); 
exports.sockets = io.sockets; 

io.sockets.on('connection', function (socket) { 

    socket.on('disconnect', function(){ 
     console.log("device "+socket.id+" disconnected"); 
    }); 

    socket.on('upload', function (data) { //The client will trigger the upload sending the data 
     /* 
      some code creating the bucket params using data 
     */ 
     S3Upload.upload(params,this); 
    }); 
}); 

S3Upload.upload = function upload(params,socket) { // Here we pass the socket so we can answer him back 
    // 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() { 
     socket.emit('progress', {progress:(uploader.progressAmount/uploader.progressTotal)*100}); 
    }), 

    uploader.on('end', function(){ 
     S3Upload.deleteFile(params.localFile); 
    }); 
}; 
+0

मैंने अंतर्निहित कोड आर्किटेक्चर को दिखाने के लिए अपना प्रश्न संपादित किया है। मैं बस कनेक्शन पर उत्सर्जित नहीं कर सकता, क्योंकि मैं सॉकेट में किसी अन्य मार्ग से जानकारी पास कर रहा हूं। –

+0

मैंने अपना कोड आपके कोड के अनुसार संपादित किया है, मैंने इसे आसान बनाने के लिए उसी फ़ाइल में 'socket.js' और' s3upload.js' विलय कर दिया है। यदि आपको वास्तव में उन्हें अलग रखने की आवश्यकता है, तो मैं आपको S3.js आयात करने वाली निर्भरता को टॉगल करने की अनुशंसा करता हूं, न कि दूसरी तरफ। आपको सॉकेट ईवेंट के आधार पर फ़ंक्शंस कॉल करने की आवश्यकता होगी, इसलिए इसे 's3upload.js' फ़ंक्शंस तक पहुंचने की आवश्यकता होगी। –

+0

मैं सहायता के लिए धन्यवाद, आपके सुझावों के साथ अपने ऐप को पुन: आर्किटेक्चर करने का प्रयास करूंगा। मेरे कोड को चारों ओर स्थानांतरित करने के आपके सुझाव के आधार पर संबंधित प्रश्न: क्या यह सच है कि सॉकेट का उपयोग करते समय, ऐप्स को वास्तव में सॉकेट.io के आसपास डिज़ाइन किया जाना चाहिए, ताकि सभी तर्क सॉकेट हैंडलर के माध्यम से पारित हो जाएं? यदि यह सच है, तो क्या सॉकेट का उपयोग करते समय समर्पित मार्गों को लिखना असंभव नहीं होगा? –

1

दस्तावेज़ीकरण के अनुसार सभी उपयोगकर्ता सॉकेट आईडी द्वारा पहचाने गए default room में शामिल होते हैं, इसलिए कनेक्शन पर शामिल होने की कोई आवश्यकता नहीं है। इसके बावजूद, यदि आप एक विशिष्ट सॉकेट से नामस्थान में किसी कमरे में उत्सर्जित करना चाहते हैं तो आपको socket.broadcast.to(room).emit('my message', msg) का उपयोग करना चाहिए, यह देखते हुए कि आप उस विशिष्ट कमरे से जुड़े सभी ग्राहकों को संदेश प्रसारित करना चाहते हैं।

+0

मेरे कोड को अपडेट करने के साथ दे रही है मुझे एक ही समस्या है। यह पार्सर चला रहा है, लेकिन इंजन या रीडस्ट्रीम नहीं। मैं सॉकेट.io 1.3.6 चला रहा हूं, इसलिए इन कार्यों को निश्चित रूप से परिभाषित किया गया है। अगर मुझे अपना अधिक कोड देखने में मदद मिलेगी, तो मुझे बताएं, या अगर इसे आगे डीबग करने का कोई तरीका है तो मैं कोशिश नहीं कर रहा हूं। –

1

सभी नए कनेक्शन स्वचालित रूप से नाम है कि उनके सॉकेट के बराबर है होने के कमरे में शामिल हो गए हैं: आप S3 संचालन के लिए सॉकेट कनेक्शन से जोड़ने के लिए एक अलग तरह से खोजने की जरूरत होगी तुम सच में उन्हें अलग रखने के लिए की जरूरत है .id। आप इसे विशिष्ट उपयोगकर्ता को संदेश भेजने के लिए उपयोग कर सकते हैं, लेकिन आपको इस उपयोगकर्ता द्वारा प्रारंभ किए गए कनेक्शन से जुड़े socket.id को जानना होगा। आप (इसके लिए एक सरणी होने से डेटाबेस के माध्यम से, या स्मृति में) तय करने के लिए क्या आप इस संबद्धता का प्रबंधन करेगा, लेकिन एक बार तुम्हारे पास है, बस के माध्यम से प्रगति प्रतिशत भेजें:

socket.broadcast.to(user_socket_id).emit("progress", number_or_percent); 
संबंधित मुद्दे