मैं बुनियादी "लांग पोलिंग" कैसे लागू करूँ?


776

मैं बहुत सारी जानकारी पा सकता हूँ कि लांग पोलिंग कैसे काम करती है (उदाहरण के लिए, यह और यह ), लेकिन कोड में इसे कैसे लागू किया जाए, इसका कोई सरल उदाहरण नहीं है

सभी मुझे मिल सकता है धूमकेतु , जो डोजो जेएस फ्रेमवर्क पर निर्भर करता है, और एक काफी जटिल सर्वर सिस्टम है।

मूल रूप से, मैं अपाचे का उपयोग अनुरोधों को पूरा करने के लिए कैसे करूंगा, और मैं एक सरल स्क्रिप्ट (PHP में) कैसे लिखूंगा, जो नए संदेशों के लिए सर्वर को "लंबे समय से प्रदूषित" करेगा?

उदाहरण के लिए स्केलेबल, सुरक्षित या पूर्ण होना आवश्यक नहीं है, बस काम करने की आवश्यकता है!

जवाबों:


512

यह आसान है कि मैंने शुरू में सोचा था .. मूल रूप से आपके पास एक पृष्ठ है जो कुछ भी नहीं करता है, जब तक कि आप जो डेटा भेजना चाहते हैं वह उपलब्ध है (कहिए, एक नया संदेश आता है)।

यहां एक बहुत ही बुनियादी उदाहरण है, जो 2-10 सेकंड के बाद एक साधारण स्ट्रिंग भेजता है। 404 त्रुटि को वापस करने का 1 में 3 मौका (आने वाले जावास्क्रिप्ट उदाहरण में त्रुटि से निपटने के लिए)

msgsrv.php

<?php
if(rand(1,3) == 1){
    /* Fake an error */
    header("HTTP/1.0 404 Not Found");
    die();
}

/* Send a string after a random number of seconds (2-10) */
sleep(rand(2,10));
echo("Hi! Have a random number: " . rand(1,10));
?>

नोट: एक वास्तविक साइट के साथ, अपाचे जैसे नियमित वेब-सर्वर पर इसे चलाने से सभी "कार्यकर्ता थ्रेड्स" जल्दी से जुड़ जाएंगे और इसे अन्य अनुरोधों का जवाब देने में असमर्थ हो जाएगा। इसके चारों ओर तरीके हैं, लेकिन इसे लिखने की सिफारिश की गई है पायथन के मुड़ की तरह कुछ में एक "लंबे समय से मतदान सर्वर" , जो प्रति अनुरोध एक थ्रेड पर निर्भर नहीं करता है। धूमकेतु एक लोकप्रिय एक है (जो कई भाषाओं में उपलब्ध है), और टॉर्नेडो एक नया ढांचा है जो विशेष रूप से ऐसे कार्यों के लिए बनाया गया है (इसे फ्रेंडफीड के लंबे-मतदान कोड के लिए बनाया गया था) ... लेकिन एक सरल उदाहरण के रूप में, अपाचे पर्याप्त से अधिक है ! यह स्क्रिप्ट आसानी से किसी भी भाषा में लिखी जा सकती है (मैंने अपाचे / PHP को चुना क्योंकि वे बहुत आम हैं, और मैं उन्हें स्थानीय रूप से चलाने के लिए हुआ)

फिर, जावास्क्रिप्ट में, आप उपरोक्त फ़ाइल ( msg_srv.php) का अनुरोध करते हैं , और प्रतिक्रिया की प्रतीक्षा करें। जब आप एक प्राप्त करते हैं, तो आप डेटा पर कार्य करते हैं। फिर आप फ़ाइल का अनुरोध करें और फिर से प्रतीक्षा करें, डेटा पर कार्य करें (और दोहराएं)

इस तरह के पृष्ठ का एक उदाहरण इस प्रकार है .. जब पृष्ठ लोड किया जाता है, तो यह msgsrv.phpफ़ाइल के लिए प्रारंभिक अनुरोध भेजता है .. यदि यह सफल होता है, तो हम संदेश को #messagesdiv पर भेजते हैं, फिर 1 सेकंड के बाद हम फिर से waForMsg फ़ंक्शन को कॉल करते हैं: जो प्रतीक्षा को ट्रिगर करता है।

1 सेकंड setTimeout()वास्तव में एक मूल दर-सीमक है, यह इसके बिना ठीक काम करता है, लेकिन अगर msgsrv.php हमेशा तुरंत लौटता है (सिंटैक्स त्रुटि के साथ, उदाहरण के लिए) - आप ब्राउज़र को बाढ़ देते हैं और यह जल्दी से फ्रीज कर सकता है। यदि फ़ाइल में एक वैध JSON प्रतिक्रिया होती है, और / या प्रति-मिनट / सेकंड का कुल चल रहा है, और उचित रूप से रोक रहा है, तो यह बेहतर होगा।

यदि पृष्ठ त्रुटियां हैं, तो यह त्रुटि को #messagesdiv पर जोड़ता है , 15 सेकंड प्रतीक्षा करता है और फिर पुन: प्रयास करता है (प्रत्येक संदेश के लिए 1 सेकंड प्रतीक्षा करने के समान)

इस दृष्टिकोण के बारे में अच्छी बात यह है कि यह बहुत लचीला है। यदि क्लाइंट इंटरनेट कनेक्शन मर जाता है, तो यह समय समाप्त हो जाएगा, फिर प्रयास करें और पुन: कनेक्ट करें - यह अंतर्निहित है कि कितने समय में मतदान कार्य, कोई जटिल त्रुटि-हैंडलिंग की आवश्यकता नहीं है

वैसे भी, long_poller.htmकोड, jQuery फ्रेमवर्क का उपयोग कर:

<html>
<head>
    <title>BargePoller</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>

    <style type="text/css" media="screen">
      body{ background:#000;color:#fff;font-size:.9em; }
      .msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
      .old{ background-color:#246499;}
      .new{ background-color:#3B9957;}
    .error{ background-color:#992E36;}
    </style>

    <script type="text/javascript" charset="utf-8">
    function addmsg(type, msg){
        /* Simple helper to add a div.
        type is the name of a CSS class (old/new/error).
        msg is the contents of the div */
        $("#messages").append(
            "<div class='msg "+ type +"'>"+ msg +"</div>"
        );
    }

    function waitForMsg(){
        /* This requests the url "msgsrv.php"
        When it complete (or errors)*/
        $.ajax({
            type: "GET",
            url: "msgsrv.php",

            async: true, /* If set to non-async, browser shows page as "Loading.."*/
            cache: false,
            timeout:50000, /* Timeout in ms */

            success: function(data){ /* called when request to barge.php completes */
                addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
                setTimeout(
                    waitForMsg, /* Request next message */
                    1000 /* ..after 1 seconds */
                );
            },
            error: function(XMLHttpRequest, textStatus, errorThrown){
                addmsg("error", textStatus + " (" + errorThrown + ")");
                setTimeout(
                    waitForMsg, /* Try again after.. */
                    15000); /* milliseconds (15seconds) */
            }
        });
    };

    $(document).ready(function(){
        waitForMsg(); /* Start the inital request */
    });
    </script>
</head>
<body>
    <div id="messages">
        <div class="msg old">
            BargePoll message requester!
        </div>
    </div>
</body>
</html>

7
क्या इस विचार का उपयोग करके कुछ संदेश नहीं खिसक सकते हैं? उस 1 सेकंड में, कहते हैं कि 1000 चैट संदेश भेजे गए, सर्वर को उस ग्राहक को विशेष रूप से 1000 संदेश भेजने का पता कैसे चलेगा?
DevDevDev

15
शायद। यह एक बहुत ही सरल उदाहरण है, अवधारणा को प्रदर्शित करने के लिए .. यह बेहतर करने के लिए आपको अधिक विस्तृत सर्वर-साइड कोड की आवश्यकता होगी, जहां यह उस विशिष्ट ग्राहक के लिए उन 1000 संदेशों को संग्रहीत करेगा, और उन्हें एक ही भाग में भेज देगा। आप प्रतीक्षा को सुरक्षित रूप से कम कर सकते हैंमॉर्गेस टाइमआउट
dbr

21
नोडज लंबे समय के मतदान अनुरोधों के लिए एक और उत्कृष्ट सर्वर साइड समाधान है, अतिरिक्त लाभ (ओवर ट्विस्टेड) ​​के साथ कि आप जावास्क्रिप्ट में सर्वर कोड भी लिख सकते हैं।
कर्क राशि

8
यह केवल 1 सेकंड के अंतराल के साथ सर्वर पर एक सादा आवर्ती AJAX कनेक्शन है। इसका "लंबे मतदान" से कोई लेना-देना नहीं है। लंबे समय तक मतदान को जीवित रखना चाहिए, जब तक कि ग्राहक समय समाप्त हो जाता है।
डेले

6
सवाल यह है कि एक वास्तविक PHP स्क्रिप्ट क्या करती है sleep(rand(2,10));? कुछ भी नहीं करने के लिए, डेटाबेस को प्रत्येक 100 मिलिसेक को प्रदूषित करें? कब मरना तय है?
लुइस सिकोट

41

मुझे स्लश के भाग के रूप में एक बहुत ही सरल चैट उदाहरण मिला है ।

संपादित करें : (हर किसी के यहाँ अपना कोड चिपकाने के बाद)

यह लंबे समय से मतदान और स्लैश का उपयोग करके संपूर्ण JSON- आधारित बहु-उपयोगकर्ता चैट है । यह कॉल करने के तरीके का डेमो है, इसलिए कृपया XSS समस्याओं को अनदेखा करें। किसी को भी इसे पहले स्वच्छता के बिना तैनात नहीं करना चाहिए।

ध्यान दें कि क्लाइंट के पास हमेशा सर्वर से कनेक्शन होता है, और जैसे ही कोई भी संदेश भेजता है, सभी को इसे लगभग तुरंत देखना चाहिए।

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Copyright (c) 2008 Dustin Sallings <dustin+html@spy.net> -->
<html lang="en">
  <head>
    <title>slosh chat</title>
    <script type="text/javascript"
      src="http://code.jquery.com/jquery-latest.js"></script>
    <link title="Default" rel="stylesheet" media="screen" href="style.css" />
  </head>

  <body>
    <h1>Welcome to Slosh Chat</h1>

    <div id="messages">
      <div>
        <span class="from">First!:</span>
        <span class="msg">Welcome to chat. Please don't hurt each other.</span>
      </div>
    </div>

    <form method="post" action="#">
      <div>Nick: <input id='from' type="text" name="from"/></div>
      <div>Message:</div>
      <div><textarea id='msg' name="msg"></textarea></div>
      <div><input type="submit" value="Say it" id="submit"/></div>
    </form>

    <script type="text/javascript">
      function gotData(json, st) {
        var msgs=$('#messages');
        $.each(json.res, function(idx, p) {
          var from = p.from[0]
          var msg = p.msg[0]
          msgs.append("<div><span class='from'>" + from + ":</span>" +
            " <span class='msg'>" + msg + "</span></div>");
        });
        // The jQuery wrapped msgs above does not work here.
        var msgs=document.getElementById("messages");
        msgs.scrollTop = msgs.scrollHeight;
      }

      function getNewComments() {
        $.getJSON('/topics/chat.json', gotData);
      }

      $(document).ready(function() {
        $(document).ajaxStop(getNewComments);
        $("form").submit(function() {
          $.post('/topics/chat', $('form').serialize());
          return false;
        });
        getNewComments();
      });
    </script>
  </body>
</html>

1
क्या मुझे पता है कि यह हमेशा कैसे जुड़ा रहता है? क्षमा करें यदि मैं मूर्खतापूर्ण कुछ पूछ रहा हूं, लेकिन मैं यह जानना चाहता हूं।
रॉकी सिंह

4
यह HTTP GET करता है और सर्वर GET को तब तक ब्लॉक करता है जब तक कि डेटा उपलब्ध न हो। जब डेटा सर्वर पर आता है, तो सर्वर डेटा को क्लाइंट को वापस कर देता है, जो कुछ भी हो सकता है उसे कतार में लगाता है और फिर ग्राहक फिर से गायब हो जाता है और यदि कोई हो, तो उसे गायब कर देता है, अन्यथा यह फिर से ब्लॉक हो जाता है।
डस्टिन

4
पहली बार में स्पष्ट नहीं हो सकता है, लेकिन बात यह है कि 'हमेशा जुड़े हुए राज्य' के लिए जिम्मेदार वहाँ कॉलबैक के साथ ajaxStop हैgetNewComments , इसलिए यह हर ajax अनुरोध के अंत में इसे पूरी तरह से आग लगा देता है
baldrs

32

टोर्नेडो को लंबे समय से मतदान के लिए डिज़ाइन किया गया है, और इसमें बहुत कम (पायथन की कुछ सौ लाइनें) चैट ऐप / उदाहरणों / चैटडेमो में शामिल हैं, जिसमें सर्वर कोड और जेएस क्लाइंट कोड शामिल हैं। यह इस तरह काम करता है:

  • ग्राहक जेएस का उपयोग तब से अपडेट के लिए पूछते हैं (अंतिम संदेश की संख्या), सर्वर यूआरएलहैंडलर इन्हें प्राप्त करता है और ग्राहक को एक कतार में जवाब देने के लिए कॉलबैक जोड़ता है।

  • जब सर्वर को एक नया संदेश मिलता है, तो ऑन्समेस इवेंट फायर करता है, कॉलबैक के माध्यम से लूप करता है, और संदेश भेजता है।

  • क्लाइंट-साइड JS संदेश प्राप्त करता है, इसे पेज पर जोड़ता है, फिर इस नई संदेश आईडी के बाद से अपडेट मांगता है।


25

मुझे लगता है कि ग्राहक एक सामान्य अतुल्यकालिक AJAX अनुरोध की तरह दिखता है, लेकिन आप इसे वापस आने के लिए "लंबा समय" लेने की उम्मीद करते हैं।

सर्वर तब ऐसा दिखता है।

while (!hasNewData())
    usleep(50);

outputNewData();

तो, AJAX का अनुरोध सर्वर पर जाता है, संभवत: एक टाइमस्टैम्प सहित जब इसे अंतिम अपडेट किया गया ताकि आपका hasNewData()पता चले कि आपको पहले से कौन सा डेटा मिला है। सर्वर तब लूप स्लीपिंग में बैठता है जब तक कि नया डेटा उपलब्ध न हो। सभी समय, आपका AJAX अनुरोध अभी भी जुड़ा हुआ है, बस डेटा के इंतजार में वहां लटका हुआ है। अंत में, जब नया डेटा उपलब्ध होता है, तो सर्वर इसे आपके AJAX अनुरोध के लिए देता है और कनेक्शन बंद कर देता है।


10
यह एक व्यस्त प्रतीक्षा है जो आपके वर्तमान धागे को अवरुद्ध करता है। यह बिल्कुल भी पैमाना नहीं है।
राउटर लवेन्स

10
नहीं, usleep एक व्यस्त प्रतीक्षा नहीं है। और "प्रतीक्षा" का पूरा बिंदु थोड़ी देर के लिए अपने धागे को अवरुद्ध करना है। संभवतः उनका मतलब 50 मिलीसेकंड (usleep (50000)) था, लेकिन 50 माइक्रोसेकंड नहीं! लेकिन वैसे भी, एक विशिष्ट Apache / PHP सेटअप के साथ, क्या ऐसा करने का कोई अन्य तरीका है?
मैट

खैर, राजकुमार से, आप इंतजार किए बिना चैट संदेश के लिए एक अवरुद्ध कार्य नहीं कर सकते।
टॉम ज़ातो -

सच में महान! मैंने नए डेटा की जांच के लिए सर्वर में एक पुनरावर्ती कार्य किया। लेकिन कुशलतापूर्वक लंबे मतदान का उपयोग करने के लिए सबसे अच्छा उत्पाद क्या है? मैं सामान्य अपाचे का उपयोग करता हूं और जब मैं 4/5 से अधिक ब्राउज़र टैब खोलता हूं तो सर्वर प्रतिक्रिया नहीं देता है :( PHP के साथ उपयोग होने वाली किसी चीज की तलाश
आधुनिक

17

यहां कुछ कक्षाएं हैं जिनका उपयोग मैं C # में लंबे समय से मतदान के लिए करता हूं। मूल रूप से 6 वर्ग हैं (नीचे देखें)।

  1. नियंत्रक : एक वैध प्रतिक्रिया (डीबी संचालन आदि) बनाने के लिए आवश्यक प्रक्रियाएं
  2. प्रोसेसर : वेब पेज के साथ asynch संचार का प्रबंधन करता है (स्वयं)
  3. IAsynchProcessor : इस इंटरफ़ेस को कार्यान्वित करने वाली सेवा प्रक्रियाएँ उदाहरण के लिए
  4. Sevice : प्रक्रियाओं वस्तुओं कि IAsynchProcessor लागू का अनुरोध
  5. अनुरोध : आपकी प्रतिक्रिया (ऑब्जेक्ट) युक्त IAsynchProcessor आवरण
  6. प्रतिक्रिया : कस्टम ऑब्जेक्ट्स या फ़ील्ड्स शामिल हैं

2
ठीक है ... तो यह मतदान क्यों किया गया? ये वर्ग वास्तव में लंबे मतदान के उदाहरण हैं।
कैदी

वास्तविक लंबे समय से मतदान नहीं है (बस) अंतराल वर्जन बढ़ाने का अभ्यास आप एक सामान्य-सर्वेक्षण (एक संसाधन पर) का संचालन करते हैं। यह एक बड़े पैटर्न का हिस्सा है ... जो "कुछ हद तक" व्याख्या के अधीन है ... लेकिन केवल समग्र कार्यान्वयन के कुछ क्षेत्रों में। कहा कि ... इन वर्गों ने कहा कि पैटर्न का पालन करें! इसलिए यदि आपके पास इसे नीचे लाने का कारण है ... तो मुझे वास्तव में इस कारण में दिलचस्पी होगी।
कैदी जीरो

शायद इसे वोट दिया गया था क्योंकि यह सीधे तौर पर एक सरल कोड उदाहरण के प्रश्न को संबोधित नहीं करता है। बेशक मैंने इसे वोट नहीं दिया इसलिए मैं केवल अनुमान लगा सकता हूं।
एंड्रयू

16

PHP और jQuery का उपयोग करके लंबे समय तक मतदान करने के लिए यह 5 मिनट का एक अच्छा पेंच है: http://screenr.com/SNH

कोड काफी ऊपर dbr के उदाहरण के समान है ।


3
मुझे लगता है कि आपको इसे केवल लंबे समय के मतदान के लिए एक परिचय के रूप में देखना चाहिए क्योंकि यह कार्यान्वयन कई समवर्ती उपयोगकर्ताओं के साथ आपके सर्वर को निश्चित रूप से मार देगा।
अल्फ्रेड

IM यह सब सीखने के बारे में ... कितना भरोसेमंद है, या नहीं, क्या यह कुछ उपयोगकर्ताओं के साथ है ... कहते हैं कि 10 आगे पीछे चैट करना?
सोमडॉ

12

यहाँ हेडर का उपयोग करके एरिक डबेलबोअर द्वारा PHP में एक सरल दीर्घकालिक मतदान उदाहरण दिया गया हैContent-type: multipart/x-mixed-replace :

<?

header('Content-type: multipart/x-mixed-replace; boundary=endofsection');

// Keep in mind that the empty line is important to separate the headers
// from the content.
echo 'Content-type: text/plain

After 5 seconds this will go away and a cat will appear...
--endofsection
';
flush(); // Don't forget to flush the content to the browser.


sleep(5);


echo 'Content-type: image/jpg

';

$stream = fopen('cat.jpg', 'rb');
fpassthru($stream);
fclose($stream);

echo '
--endofsection
';

और यहाँ एक डेमो है:

http://dubbelboer.com/multipart.php


11

मैं प्रयोग किया जाता है इस धूमकेतु के साथ पकड़ करने के लिए, मैं भी जावा Glassfish सर्वर का उपयोग कर धूमकेतु की स्थापना की और cometdaily.com की सदस्यता लेकर अन्य उदाहरण के बहुत सारे मिल गया है



9

नीचे एक लंबा मतदान समाधान है जो मैंने Inform8 वेब के लिए विकसित किया है। मूल रूप से आप वर्ग को ओवरराइड करते हैं और लोडडेटा विधि को लागू करते हैं। जब लोडडेटा मान लौटाता है या ऑपरेशन का समय निकलता है तो यह परिणाम प्रिंट करेगा और वापस लौटाएगा।

यदि आपकी स्क्रिप्ट की प्रोसेसिंग में 30 सेकंड से अधिक समय लग सकता है, तो आपको set_time_limit () कॉल को कुछ लंबे समय तक बदलने की आवश्यकता हो सकती है।

अपाचे 2.0 लाइसेंस। GitHub पर नवीनतम संस्करण https://github.com/ryanhend/Inform8/blob/master/Inform8-web/src/config/lib/Inform8/longpoll/LongPoller.php

रयान

abstract class LongPoller {

  protected $sleepTime = 5;
  protected $timeoutTime = 30;

  function __construct() {
  }


  function setTimeout($timeout) {
    $this->timeoutTime = $timeout;
  }

  function setSleep($sleep) {
    $this->sleepTime = $sleepTime;
  }


  public function run() {
    $data = NULL;
    $timeout = 0;

    set_time_limit($this->timeoutTime + $this->sleepTime + 15);

    //Query database for data
    while($data == NULL && $timeout < $this->timeoutTime) {
      $data = $this->loadData();
      if($data == NULL){

        //No new orders, flush to notify php still alive
        flush();

        //Wait for new Messages
        sleep($this->sleepTime);
        $timeout += $this->sleepTime;
      }else{
        echo $data;
        flush();
      }
    }

  }


  protected abstract function loadData();

}

8

कोड के लिए धन्यवाद, dbr । लाइन के चारों ओर long_poller.htm में बस एक छोटा टाइपो

1000 /* ..after 1 seconds */

मुझे लगता है कि यह होना चाहिए

"1000"); /* ..after 1 seconds */

इसके लिए काम करना है।

रुचि रखने वालों के लिए, मैंने एक Django समकक्ष की कोशिश की। एक नई Django परियोजना शुरू, लंबे मतदान के लिए एलपी कहते हैं :

django-admin.py startproject lp

संदेश सर्वर के लिए एप्लिकेशन msgsrv पर कॉल करें:

python manage.py startapp msgsrv

में निम्नलिखित पंक्तियां जोड़ें settings.py एक है करने के लिए टेम्पलेट्स निर्देशिका:

import os.path
PROJECT_DIR = os.path.dirname(__file__)
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, 'templates'),
)

में अपना URL पैटर्न को परिभाषित करें urls.py जैसे:

from django.views.generic.simple import direct_to_template
from lp.msgsrv.views import retmsg

urlpatterns = patterns('',
    (r'^msgsrv\.php$', retmsg),
    (r'^long_poller\.htm$', direct_to_template, {'template': 'long_poller.htm'}),
)

और msgsrv / views.py तरह दिखना चाहिए:

from random import randint
from time import sleep
from django.http import HttpResponse, HttpResponseNotFound

def retmsg(request):
    if randint(1,3) == 1:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        sleep(randint(2,10))
        return HttpResponse('Hi! Have a random number: %s' % str(randint(1,10)))

अंत में, टेम्प्लेट / long_poller.htm टाइपो के साथ ठीक किए गए के समान होना चाहिए। उम्मीद है की यह मदद करेगा।


दरअसल, "15000"वाक्यविन्यास त्रुटि है। setTimeout अपने 2 पैरामीटर के रूप में पूर्णांक लेता है।
एंड्रयू हेड्स

इस जवाब के लिए काम की जरूरत है। यह एक या एक से अधिक टिप्पणियों की परिणति है और एक अलग उत्तर या उत्तर है।
ब्रायन वेबस्टर

8

यह उन परिदृश्यों में से एक है जो PHP के लिए एक बहुत बुरा विकल्प है। जैसा कि पहले उल्लेख किया गया है, आप अपने सभी अपाचे श्रमिकों को बहुत जल्दी कुछ ऐसा कर सकते हैं। PHP का निर्माण स्टार्ट, एक्जिट, स्टॉप के लिए किया गया है। यह शुरुआत के लिए नहीं बनाया गया है, प्रतीक्षा करें ... निष्पादित करें, रोकें। आप बहुत तेज़ी से अपने सर्वर को बंद कर देंगे और पाएंगे कि आपको अविश्वसनीय स्केलिंग की समस्या है।

उस ने कहा, आप अभी भी PHP के साथ ऐसा कर सकते हैं और यह nginx HttpPushStreamModule का उपयोग करके अपने सर्वर को नहीं मार सकता है: http://wiki.nginx.org/HttpPushStreamModule

आप Apache (या जो कुछ भी) के सामने nginx को सेटअप करते हैं और यह समवर्ती कनेक्शनों को खोलने का ध्यान रखेगा। आप बस एक आंतरिक पते पर डेटा भेजकर पेलोड के साथ प्रतिक्रिया करते हैं जो आप पृष्ठभूमि की नौकरी के साथ कर सकते हैं या बस उन संदेशों को बंद कर सकते हैं जो नए अनुरोध आने पर इंतजार कर रहे थे। यह लंबे समय तक मतदान के दौरान पीएचपी प्रक्रियाओं को खुला रखने से रोकता है।

यह PHP के लिए विशेष नहीं है और किसी भी बैकएंड भाषा के साथ nginx का उपयोग करके किया जा सकता है। समवर्ती खुले कनेक्शन लोड Node.js के बराबर है, इसलिए सबसे बड़ा पर्क यह है कि यह आपको कुछ इस तरह के लिए NEEDING नोड से बाहर कर देता है।

आप बहुत से अन्य लोगों को लंबे मतदान को पूरा करने के लिए अन्य भाषा पुस्तकालयों का उल्लेख करते हुए देखते हैं और यह अच्छे कारण के साथ है। PHP स्वाभाविक रूप से इस प्रकार के व्यवहार के लिए अच्छी तरह से निर्मित नहीं है।


क्या यह अपाचे समस्या या PHP समस्या है? अगर मेरा PHP कोड सीधे nginx या lighttpd पर चला गया तो क्या मेरे पास लंबे मतदान के मुद्दे होंगे?
डेविड

यह एक PHP समस्या कम है और एक PHP दुरुपयोग अधिक है। हर अनुरोध पर PHP स्क्रैच से स्क्रिप्ट चलाता है, आवश्यकतानुसार पुस्तकालयों को लोड करता है, अपने कोड को निष्पादित करता है और फिर अनुरोध में शुरू की गई सभी चीजों को इकट्ठा करते समय कचरा बंद कर देता है। देर से स्थैतिक बाइंडिंग, आलसी लोडिंग, मेमोरी बाईटेकोड कैश में डिस्क I / O, आदि जैसे प्रभाव को कम करने के लिए PHP में बहुत सारे संशोधन किए गए हैं। समस्या यह है कि PHP शुरू करने और जल्द से जल्द बंद करने का इरादा है। यथासंभव। ऐसी भाषाएं जो एक बार लोड हो जाएंगी / बूट हो जाएंगी और अनुरोध के लिए एक धागा खोलना लंबे मतदान के लिए बेहतर होगा।
उज्ज्वल जूल

लेकिन सवाल का जवाब देने के लिए, हाँ आप इस मुद्दे का अनुभव करेंगे कि आप अपाचे का उपयोग कर रहे हैं या कुछ और। यह है कि PHP कैसे काम करती है। मुझे यह कहने के लिए संशोधन करना चाहिए कि, यदि आप एक ज्ञात अधिकतम ट्रैफ़िक लोड करने जा रहे हैं तो PHP ठीक रहेगा। मैंने PHP का उपयोग करके एम्बेडेड सिस्टम देखा है जिसमें कोई समस्या नहीं है क्योंकि केवल कुछ ही कनेक्शन हैं। संभावित रूप से एक कंपनी इंट्रानेट पर यह भी निष्क्रिय हो सकता है। हालाँकि, सार्वजनिक रूप से आने वाले अनुप्रयोगों के लिए, आप ट्रैफ़िक के बढ़ने पर अपने सर्वर को बिल्कुल मार डालेंगे।
उज्ज्वल

4

लंबे मतदान के बजाय वेब सॉकेट पर विचार क्यों नहीं किया जाता है? वे सेटअप करने में बहुत कुशल और आसान हैं। हालांकि वे केवल आधुनिक ब्राउज़रों में समर्थित हैं। यहाँ एक त्वरित संदर्भ है


मुझे लगता है कि एक बार वेबसैट को हर जगह लागू किया जाएगा (शायद आने वाले वर्षों के लिए नहीं) वे इस तरह के आवेदन के लिए मानक होंगे। दुर्भाग्य से अब के लिए, हम उन पर उत्पादन ऐप्स के लिए भरोसा नहीं कर सकते।
रिचर्ड

3
@ रिचर्ड आप सॉकेट की तरह कुछ का उपयोग कर सकते हैं। I जो स्वत: फॉलबैक ट्रांसपोर्ट प्रदान करता है, जो आईई 6. के लिए नीचे सभी तरह से वेब-सॉकेट जैसी कार्यक्षमता प्रदान करता है
ब्रैड

3

WS-I समूह ने "विश्वसनीय सुरक्षित प्रोफ़ाइल" नामक कुछ प्रकाशित किया जिसमें ग्लास फ़िश और .NET कार्यान्वयन है जो स्पष्ट रूप से अच्छी तरह से संचालित होते हैं।

किसी भी भाग्य के साथ एक जावास्क्रिप्ट वहाँ भी लागू होता है।

एक सिल्वरलाइट कार्यान्वयन भी है जो HTTP डुप्लेक्स का उपयोग करता है आप पुशबैक होने पर कॉलबैक पाने के लिए जावास्क्रिप्ट को सिल्वरलाइट ऑब्जेक्ट से कनेक्ट कर सकते हैं

वहाँ भी वाणिज्यिक भुगतान किया संस्करण में अच्छी तरह से।


2

ASP.NET MVC कार्यान्वयन के लिए, सिग्नलग्रे को देखें जो कि NuGet पर उपलब्ध है .. ध्यान दें कि NuGet अक्सर Git स्रोत से पुराना हो जाता है जो बहुत बार कमिट हो जाता है।

स्कॉट हंसेलमैन के एक ब्लॉग पर सिग्नलआर के बारे में और पढ़ें


2

आप icomet ( https://github.com/ideawu/icomet ), एक C1000K C ++ धूमकेतु सर्वर को मानहानि के साथ निर्मित करने का प्रयास कर सकते हैं। icomet एक JavaScript लाइब्रेरी भी प्रदान करता है, इसे उपयोग करना आसान है

var comet = new iComet({
    sign_url: 'http://' + app_host + '/sign?obj=' + obj,
    sub_url: 'http://' + icomet_host + '/sub',
    callback: function(msg){
        // on server push
        alert(msg.content);
    }
});

icomet ब्राउज़र और OS की एक विस्तृत श्रृंखला का समर्थन करता है, जिसमें Safari (iOS, Mac), IEs (Windows), फ़ायरफ़ॉक्स, क्रोम, आदि शामिल हैं।


0

सरलतम NodeJS

const http = require('http');

const server = http.createServer((req, res) => {
  SomeVeryLongAction(res);
});

server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});

server.listen(8000);

// the long running task - simplified to setTimeout here
// but can be async, wait from websocket service - whatever really
function SomeVeryLongAction(response) {
  setTimeout(response.end, 10000);
}

एक्सप्रेसवे में उत्पादन वार परिदृश्य आपको responseमिडलवेयर में मिलेगा । क्या आप क्या करने की जरूरत है, नक्शे या कुछ करने के लिए लंबे समय से मतदान के तरीकों के सभी गुंजाइश कर सकते हैं (जो अन्य प्रवाह के लिए दिखाई देता है), और <Response> response.end()जब भी आप तैयार हों तब आह्वान करें । लंबे समय से प्रदूषित कनेक्शनों के बारे में कुछ खास नहीं है। बाकी है कि आप सामान्य रूप से अपने आवेदन को कैसे बनाते हैं।

यदि आप नहीं जानते कि मुझे डांटने से क्या मतलब है, तो आपको यह विचार देना चाहिए

const http = require('http');
var responsesArray = [];

const server = http.createServer((req, res) => {
  // not dealing with connection
  // put it on stack (array in this case)
  responsesArray.push(res);
  // end this is where normal api flow ends
});

server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});

// and eventually when we are ready to resolve
// that if is there just to ensure you actually 
// called endpoint before the timeout kicks in
function SomeVeryLongAction() {
  if ( responsesArray.length ) {
    let localResponse = responsesArray.shift();
    localResponse.end();
  }
}

// simulate some action out of endpoint flow
setTimeout(SomeVeryLongAction, 10000);
server.listen(8000);

जैसा कि आप देखते हैं, आप वास्तव में सभी कनेक्शनों का जवाब दे सकते हैं, एक, जो आप चाहते हैं वह करें। idहर अनुरोध के लिए है , इसलिए आपको मैप का उपयोग करने में सक्षम होना चाहिए और आपी कॉल से विशिष्ट उपयोग करना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.