2013-04-12 13 views
6

Temel olarak, node.js kullanarak sıfırdan temel bir kuyruklu yıldız sunucu ve istemci kurmaya çalışıyorum. Çalışması gereken süreç hakkında Google'a denemeler denedim ve test ettiğim gibi iyi çalışıyor gibi görünüyor. Ancak yine de bir sorum kafamda. İlk önce size kodu göstermek istiyorum.Node.js ve Comet

var http = require('http'); 
var sys = require('sys'); 
var fs = require('fs'); 
var qs = require('querystring'); 

var server = http.createServer(); 

var connections = []; 

server.on('request', function(req, res) { 

    console.log(req.url); 

    if(req.url == '/index') { 

     fs.readFile(__dirname + '/index.html', function(err, data){ 
      if(err) { 
       res.writeHead(err, data); 
       return res.end('Error loading index.html'); 
      } 

      res.writeHead(200); 
      res.end(data); 
     }); 
    } else if(req.url == '/sendData') { 
     if (req.method == 'POST') { 
      var body = ''; 
      req.on('data', function (data) { 
       body += data; 
      }); 
      req.on('end', function() { 

       var POST = qs.parse(body); 
       console.log(POST); 
       res.writeHead(200); 
       res.end(""); 
       broadcastData(POST); 
      }); 
     } 

    } else { 
     connections.push(res); 
    } 
}); 

function broadcastData(data) { 
    for(var i = 0; i < connections.length; i++) { 
     connections[i].writeHead(200); 
     connections[i].end(JSON.stringify({'message': data})); 
    } 
} 

process.openStdin().addListener('data', function(chunk) { 
    for(var i = 0; i < connections.length; i++) { 
     connections[i].writeHead(200); 
     var message = chunk.toString(); 
     connections[i].end(JSON.stringify({'message': {'name': message}})); 
    } 
}); 

server.listen(4000); 

istemci tarafı:

function doComet() { 
    $.getJSON('/', function(events){ 
     doComet(); 
     console.log(events); 
     $('#content').append(events.message.name); 
    }); 
} 

function sendData(data) { 
    $.ajax({ 
     type: "POST", 
     url: "/sendData", 
     contentType: 'application/javascript; charset=UTF-8', 
     data: { name: "John", location: "Boston" } 
    }).done(function(msg) { 
     console.log(msg) 
    }); 
} 

Yani orada ben stdin yazmak ve ayrıca sunucusuna veri gönderir istemci tarafında bir düğme var veri gönderen bir dinleyici ve Sunucu tüm istemcilere gönderir.

Sorum şu: Çok kısa bir süre içinde çok sayıda olay meydana gelirse? Yani, sunucudan bir yanıt geldiğinde, başka bir ajax isteği gönderilir, ancak istemcinin henüz bağlanmadığı bir zamanda kısa bir süre olmalıdır ve bu süre zarfında bir şey olursa, müşteri yeni verilere sahip olmayacaktır.

Düşüncelerim bu konuda doğru mu? Bu durumda, herkesin aldığından emin olmak için verileri düzgün bir şekilde senkronize etmeliyim. Bunu nasıl yapacaklarını bilen var mı?

Yardımlarınız için teşekkür ederiz!

+0

Neden kendi kuyruk takımınızı uyguluyorsunuz? Sizin için işleyen birçok kütüphaneden birini kullanmalısınız. Http://socket.io/ – generalhenry

+3

Neden? Bu şeylerin herhangi bir bilgi olmadan kullanmaya başlamadan önce nasıl çalıştığını merak ediyorum. – stomseven

+0

Kodunuzu biraz temizlemekten çok etkilendim: http://runnable.com/UWhebgy1CIBlAACd hala sel sorunu hakkında düşünüyor – generalhenry

cevap

13

Kuyruklu yıldız, tüm eski HTTP tabanlı saldırılar için bir şemsiye terimidir ve kurtulmak istediğimiz bir deyimdir. WebSockets, olmak istediğimiz yerdir; tarayıcılar ve ötesi. Yani, gerçek zamanlı bir çözüm oluşturmada ilginç iseniz, muhtemelen önce WebSockets'ı araştırmanız ve daha sonra HTTP Akışı ve HTTP Long-Polling gibi geri dönüşlerle uğraşmanız gerekir. Daha fazla bilgi için bkz. Realtime Web Technology Transport Mechanisms.

Sağladığınız örnek, HTTP Long-Polling olarak sınıflandırılacaktır.

Gerçekten çok kısa sürede çok fazla olay gerçekleşirse ne olur? Sunucudan bir yanıt aldığında, başka bir ajax isteği gönderilir, ancak istemcinin henüz bağlanmadığı ve bu süre zarfında bir şey olursa, istemcinin yeni verilere sahip olmayacağı kısa bir süre olmalıdır.

Bu, HTTP Long-Polling ile kısıtlamalardan biridir ve HTTP Streaming'in neden daha iyi bir çözüm olduğunu ve WebSockets'ların hala daha iyi olduğunu - veri gönderildiğinde bağlantı kapatılmaz. Her türlü anket çözümüyle, yoklama istekleri sırasında gönderilen ve gönderilen iletilerin yoklama istemcisi tarafından kaçırılmamasını sağlayan bir çözüme ihtiyaç duyacaksınız.

  1. Kullanım oturumları belirli bir müşteri gönderdiği son mesajın izlemek için:

    çözümleri bir çift vardır. Yeniden bağlandıklarında hangi mesajların en son gönderilip gönderilmediğini kontrol edin, hangi mesajlar atlandı ve gönderilsin.

  2. İstemci yoklamanın bir parçası olarak bir lastMessageId gönderin. Sunucu bunu aldığında, bunun son mesaj olup olmadığını kontrol edebilirsiniz. Değilse cevapsız mesajlarla cevap verebilirsiniz.

Gerçek zamanlı web teknolojilerine sahip karmaşıklıklardan biri, olası tüm bağlantı senaryolarını ele almaktır. Yani, bunu bir öğrenme deneyimi olarak yapıyorsanız, o zaman kesinlikle yararlı ve eğlenceli. Ancak, üretime geçmek için bir uygulama oluşturuyorsanız, mevcut bir gerçek zamanlı çerçeveyi öneriyorum. realtime web tech guide'a bakın.

+0

Cevabınız için teşekkürler. Evet, websockets kullanıyorum, ancak yaygın olarak desteklenecek zamana ihtiyacı var. İşte bu yüzden daha tarayıcı uyumlu bir şekilde nasıl yapılacağını anlamaya çalışıyorum. Yazdığınız aynı çözümleri düşünüyorum ama uygulayamadan önce bunu yapmanın daha iyi bir yolu olup olmadığını öğrenmek istedim. – stomseven

+0

WebKontrolleri çok yaygın olarak desteklenmektedir. Http://caniuse.com/#feat=websockets adresine bakın. Pusher için çalışmamdaki deneyimime dayanarak% 70'den daha büyük olduğunu söyleyebilirim. Yine de,% 100 destek için HTTP tabanlı yedeklere ihtiyacımız var. Cevabım sorunuzu cevaplıyor mu? – leggetter

+0

@leggetter WebsSockets kullanıyorsanız ve hala WebSocket sınırlaması olan çok platformlu bir uygulama için tatmin etmek üzere HTTP tabanlı geri dönüşler kullanmanız gerekiyorsa "Comet" terimi hala geçerli olur mu? Ayrıca, bununla uğraşan bir kütüphanede çalışan kimse var mı? – Shane