سؤال

أريد أن أعرف ما إذا كان من الممكن دفق البيانات من الخادم إلى العميل باستخدام Node.js. أرغب في نشر طلب AJAX واحد إلى Node.js ، ثم اترك الاتصال مفتوحًا ودفق البيانات باستمرار إلى العميل. سيتلقى العميل هذا الدفق وتحديث الصفحة بشكل مستمر.

تحديث:

كتحديث ل هذا الجواب - لا أستطيع أخذ هذا الى العمل. ال response.write لم يتم إرساله قبل الاتصال close. لقد قمت بإعداد برنامج مثال أستخدمه لتحقيق ذلك:

node.js:

var sys = require('sys'), 
http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    var currentTime = new Date();
    setInterval(function(){
        res.write(
            currentTime.getHours()
            + ':' + 
            currentTime.getMinutes()
            + ':' +
            currentTime.getSeconds()
        );
    },1000);
}).listen(8000);

لغة البرمجة:

<html>
    <head>
        <title>Testnode</title>
    </head>

    <body>
        <!-- This fields needs to be updated -->
        Server time: <span id="time">&nbsp;</span>

        <!-- import jQuery from google -->
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

        <!-- import jQuery -->
        <script type="text/javascript">
            $(document).ready(function(){
            // I call here node.localhost nginx ports this to port 8000
                $('#time').load('http://node.localhost');
            });
        </script>
    </body>
</html>

باستخدام هذه الطريقة لا أحصل على أي شيء حتى أتصل close(). هل هذا ممكن أم يجب أن أذهب مع نهج استطلاع طويل بدلاً من ذلك حيث أسمي وظيفة التحميل مرة أخرى عندما يأتي المرء؟

هل كانت مفيدة؟

المحلول

إنه ممكن. فقط استخدم استجابة() عدة مرات.

var body = ["hello world", "early morning", "richard stallman", "chunky bacon"];
// send headers
response.writeHead(200, {
  "Content-Type": "text/plain"
});

// send data in chunks
for (piece in body) {
    response.write(body[piece], "ascii");
}

// close connection
response.end();

قد تضطر إلى إغلاق الاتصال وإعادة فتحه كل 30 ثانية أو نحو ذلك.

تعديل: هذا هو الكود الذي اختبرته بالفعل:

var sys = require('sys'),
http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    var currentTime = new Date();
    sys.puts('Starting sending time');
    setInterval(function(){
        res.write(
            currentTime.getHours()
            + ':' +
            currentTime.getMinutes()
            + ':' +
            currentTime.getSeconds() + "\n"
        );

        setTimeout(function() {
            res.end();
        }, 10000);

    },1000);
}).listen(8090, '192.168.175.128');

لقد توصيت به بواسطة Telnet ويرى بالفعل استجابة مكثف. ولكن لاستخدامه في متصفح Ajax يجب أن يدعم XHR.ReadyState = 3 (استجابة جزئية). لا تدعم كل المتصفحات هذا ، بقدر ما أعرف. لذلك يمكنك استخدام الاقتراع الطويل (أو WebSockets لـ Chrome/Firefox).

EDIT2: أيضًا ، إذا كنت تستخدم Nginx كوكيل عكسي للعقدة ، فإنه يريد أحيانًا جمع جميع القطع وإرساله إلى المستخدم مرة واحدة. تحتاج إلى تعديلها.

نصائح أخرى

انظر إلى Sockets.io. يوفر تدفق HTTP/HTTPS ويستخدم نقل مختلف للقيام بذلك:

  • WebSocket
  • WebSocket Over Flash (+ دعم سياسة أمان XML)
  • استقصاء XHR
  • XHR Multipart تدفق
  • إلى الأبد iframe
  • الاقتراع JSONP (للمجال المتقاطع)

و! إنه يعمل بسلاسة مع Node.js. إنها أيضًا حزمة NPM.

https://github.com/learnboost/socket.io

https://github.com/learnboost/socket.io-node

يمكنك أيضًا إحباط الحلقة اللانهائية:

app.get('/sse/events', function(req, res) {
    res.header('Content-Type', 'text/event-stream');

    var interval_id = setInterval(function() {
        res.write("some data");
    }, 50);

    req.socket.on('close', function() {
        clearInterval(interval_id);
    }); 
}); 

هذا مثال على expressjs. أعتقد أنه بدون ExpressJS سيكون شيء مثل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top