Temel “Uzun Çağırma” yı nasıl uygularım?


776

Uzun Çağırma'nın nasıl çalıştığı hakkında birçok bilgi bulabilirim (Örneğin, bu ve bu ), ancak kodda nasıl uygulanacağına dair basit bir örnek yok .

Bütün bulabildiğim Dojo JS çerçevesine dayanan kuyruklu yıldız ve oldukça karmaşık bir sunucu sistemi.

Temel olarak, istekleri sunmak için Apache'yi nasıl kullanırım ve yeni mesajlar için sunucuyu "uzun süre sorgulayacak" basit bir komut dosyasını nasıl yazarım?

Örnek ölçeklenebilir, güvenli veya eksiksiz olmak zorunda değildir, sadece çalışması gerekir!

Yanıtlar:


512

Başlangıçta düşündüğümden daha basit .. Temelde, göndermek istediğiniz veriler mevcut olana kadar (yeni bir mesaj geldiğinde) hiçbir şey yapmayan bir sayfanız var.

İşte 2-10 saniye sonra basit bir dize gönderen gerçekten temel bir örnek. 404 hatası döndürme şansından 1'i (gelecek Javascript örneğinde hata işlemeyi göstermek için)

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

Not: Gerçek bir site ile, bunu Apache gibi normal bir web sunucusunda çalıştırmak, tüm "işçi iş parçacıklarını" hızlı bir şekilde bağlayacak ve diğer isteklere yanıt verememesine neden olacaktır .. Bunun için yollar vardır, ancak yazmanız önerilir Python's gibi bir şeyde "uzun anket sunucusu" istek başına bir iş parçacığına dayanmayan bükülmüş hali . cometD popülerdir (birkaç dilde mevcuttur) ve Tornado bu tür görevler için özel olarak yapılmış yeni bir çerçevedir (FriendFeed'in uzun sorgulama kodu için inşa edilmiştir) ... ancak basit bir örnek olarak Apache yeterli olmaktan daha fazlasıdır ! Bu komut dosyası kolayca herhangi bir dilde yazılabilir (Çok yaygın oldukları için Apache / PHP'yi seçtim ve bunları yerel olarak çalıştırıyorum)

Ardından, Javascript'te, yukarıdaki dosyayı ( msg_srv.php) isteyin ve bir yanıt bekleyin. Bir tane aldığınızda, veriler üzerinde hareket edersiniz. Sonra dosyayı isteyin ve tekrar bekleyin, verilere göre hareket edin (ve tekrarlayın)

Aşağıda böyle bir sayfanın bir örneği var .. Sayfa yüklendiğinde, msgsrv.phpdosya için ilk isteği gönderir .. Başarılı olursa, #messagesdiv öğesine mesaj ekleriz, sonra 1 saniye sonra tekrar waitForMsg işlevini çağırırız, ki bu beklemeyi tetikler.

1 saniye setTimeout()gerçekten temel bir hız sınırlayıcıdır, bu olmadan iyi çalışır, ancak msgsrv.php her zaman anında dönerse (örneğin bir sözdizimi hatasıyla) - tarayıcıyı sele uğrarsınız ve hızlı bir şekilde donabilir. Bu, dosyanın geçerli bir JSON yanıtı içerip içermediğini kontrol etmek ve / veya çalışan / dakika başına saniyede istek toplamını tutmak ve uygun şekilde duraklatmak daha iyi olur.

Sayfa hataları varsa, hatayı #messagesdiv öğesine ekler, 15 saniye bekler ve sonra tekrar dener (her mesajdan 1 saniye sonra nasıl beklediğimizle aynıdır)

Bu yaklaşımın güzel yanı çok esnek olmasıdır. İstemcilerin internet bağlantısı koparsa, zaman aşımına uğrar, ardından yeniden bağlanmayı dener - bu, yoklamanın ne kadar sürdüğünün doğasında bulunur, karmaşık bir hata işlemeye gerek yoktur

Her neyse, long_poller.htmjQuery çerçevesini kullanan kod:

<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
Bazı iletiler bu fikri kullanarak geçemez mi? Diyelim ki 1 saniyelik zaman aşımı süresinde 1000 sohbet mesajı gönderildi, sunucu 1000 iletiyi özel olarak bu istemciye göndermeyi nasıl bilebilirdi?
DevDevDev

15
Muhtemelen. Bu, konsepti göstermek için çok basitleştirilmiş bir örnektir. Bunu daha iyi yapabilmek için, söz konusu istemci için bu 1000 iletiyi depolayacağı ve bir yığın halinde göndereceği daha ayrıntılı sunucu tarafı koduna ihtiyacınız olacaktır. Ayrıca waitForMsg zaman aşımını güvenli bir şekilde azaltabilirsiniz
dbr

21
nodejs , uzun sorgulama istekleri için başka bir mükemmel sunucu tarafı çözümüdür ve Javascript'te de sunucu kodu yazabileceğiniz ek avantaj (Twisted over).
Husky

8
Bu, 1 saniyelik aralıklarla sunucuya basit bir yinelenen AJAX bağlantısıdır. Bunun "uzun yoklama" ile ilgisi yoktur. Uzun yoklama, istemci zaman aşımı gerçekleştiği sürece bağlantıyı canlı tutmalıdır.
Deele

6
soru, gerçek bir PHP betiği yerine ne yapıyor sleep(rand(2,10));? hiçbir şey yapmak için, her 100 milisaniye veritabanında anket? ne zaman ölmeye karar verir?
Luis Siquot

41

Slosh'un bir parçası olarak gerçekten basit bir sohbet örneğim var .

Düzenleme : (herkes kodlarını buraya yapıştırdığı için)

Bu, uzun sorgulama ve slosh kullanan eksiksiz JSON tabanlı çok kullanıcılı sohbettir . Bu bir demo aramaları nasıl yapılacağı, bu nedenle XSS sorunları önemsemeyin. Kimse bunu önce sterilize etmeden konuşlandırmamalıdır.

İstemcinin her zaman sunucuyla bir bağlantısı olduğunu ve herhangi bir ileti gönderir iletmez herkesin anında kabaca görmesi gerektiğini unutmayın.

<?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
Bunun her zaman nasıl bağlantılı olduğunu öğrenebilir miyim? Aptalca bir şey sorarsam özür dilerim, ama bunu bilmek istiyorum.
Rocky Singh

4
Bir HTTP GET yapar ve kullanılabilir veri olana kadar sunucu GET'i engeller. Veriler sunucuya ulaştığında, sunucu verileri istemciye döndürür, başka ne geliyorsa kuyruğa girer ve sonra istemci eksik bağlanır ve varsa eksik iletileri alır, aksi takdirde yeniden engeller.
Dustin

4
İlk başta belli olmayabilir, ama şey 'her zaman bağlı durum' sorumludur geri çağrı ile ajaxStopgetNewComments , bu yüzden sadece her ajax isteğinin sonunda sonsuza kadar
ateş

32

Tornado uzun yoklama için tasarlanmış ve çok az (Python birkaç yüz hatları) içerir sohbet app / de örnekler / chatdemo sunucu kodu ve JS istemci kodu dahil. Şöyle çalışır:

  • İstemciler JS'yi (son ileti sayısı), sunucu URLHandler bunları aldığından ve istemciye bir kuyruğa yanıt vermek için bir geri arama eklediğinden güncelleştirme istemek için kullanır.

  • Sunucu yeni bir ileti aldığında, onmessage olayı tetiklenir, geri aramalar arasında geçiş yapar ve iletileri gönderir.

  • İstemci tarafı JS iletiyi alır, sayfaya ekler ve ardından bu yeni ileti kimliğinden bu yana güncelleştirme ister.


25

İstemci normal bir zaman uyumsuz AJAX isteği gibi görünüyor, ancak geri gelmesi için "uzun zaman" almasını bekliyoruz.

Sunucu daha sonra böyle görünür.

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

outputNewData();

Yani, AJAX isteği sunucuya gider, muhtemelen en son güncellemenin ne zaman olduğuna dair bir zaman damgası içerir, böylece sahip hasNewData()olduğunuz verileri bilir. Sunucu daha sonra yeni veriler mevcut olana kadar bir uykuda oturur. Tüm bu süre boyunca, AJAX isteğiniz hala bağlı, sadece veri beklerken orada asılı. Son olarak, yeni veriler kullanılabilir olduğunda, sunucu verileri AJAX isteğinize verir ve bağlantıyı kapatır.


10
Bu, geçerli iş parçacığınızı engelleyen yoğun bir beklemedir. Bu hiç ölçeklenmiyor.
Wouter Lievens

10
Hayır, uykuda meşgul beklemek değildir. Ve "beklemenin" bütün amacı iş parçacığınızı bir süre engellemektir. Muhtemelen 50 mikrosaniye değil, 50 milisaniye (uykuda (50000)) demekti! Ama yine de, tipik bir Apache / PHP kurulumu ile bunu yapmanın başka bir yolu var mı?
Matt

Temelden, beklemeden sohbet mesajı için engelleme işlevi yapamazsınız.
Tomáš Zato - Monica'yı

Gerçekten harika! Yeni verileri kontrol etmek için sunucuda özyinelemeli bir işlev oluşturdum. Ancak uzun yoklamayı verimli kullanmak için en iyi ürün hangisidir? Normal Apache kullanıyorum ve 4/5'den fazla tarayıcı sekmesi açtığımda sunucu yanıt vermiyor :( PHP ile kullanılacak bir şey mi arıyorsunuz
moderns

17

İşte C # uzun yoklama için kullandığım bazı sınıflar. Temel olarak 6 sınıf vardır (aşağıya bakınız).

  1. kontrolör : Geçerli bir yanıt oluşturmak için gerekli eylemleri işler (db işlemleri vb.)
  2. İşlemci : Web sayfası (kendisi) ile eşzamansız iletişimi yönetir
  3. IAsynchProcessor : Hizmet, bu arabirimi uygulayan örnekleri işler
  4. Sevice : IAsynchProcessor uygulayan istek nesnelerini işler
  5. İstek : Yanıtınızı (nesne) içeren IAsynchProcessor sarmalayıcısı
  6. Yanıt : Özel nesneler veya alanlar içerir

2
Tamam ... Peki bu niye oylandı? Bu sınıflar gerçekten de uzun oylamanın geçerli örnekleridir.
Mahkum ZERO

Gerçek uzun oylama (basitçe), normal bir anket yaparken (bir kaynak üzerinde) aralığı artırmanın uygulaması değildir. Daha büyük bir kalıbın parçasıdır ... ki bu "bir şekilde" yoruma tabidir ... ama genel uygulamanın sadece belirli alanlarında. Dedi ki ... bu sınıflar söz konusu paterni takip ediyor! Eğer oy vermek için bir nedeniniz varsa ... Sebeple gerçekten ilgilenirim.
Mahkum SIFIR

Belki de basit bir kod örneği sorununu doğrudan ele almadığı için oylanmıştır. Tabii ki oy vermedim, bu yüzden sadece tahmin edebiliyorum.
Andrew

16

Bu PHP ve jQuery kullanarak uzun yoklama nasıl yapılır 5 dakikalık güzel bir screencast: http://screenr.com/SNH

Kod, dbr'nin yukarıdaki örneğine oldukça benzer .


3
Bence bunu sadece uzun oylamaya giriş olarak görmelisiniz, çünkü bu uygulama kesinlikle sunucunuzu birçok eşzamanlı kullanıcıyla öldürecektir.
Alfred

im sadece tüm bunları öğrenmek ... ne kadar güvenilir ya da değil, birkaç kullanıcı ile ... 10 ileri geri sohbet demek?
somdow

12

Aşağıda, başlığı kullanarak Erik Dubbelboer tarafından PHP'de basit, uzun sorgulama örneği verilmiştirContent-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
';

Ve işte bir demo:

http://dubbelboer.com/multipart.php


11

Kullandığım bu Comet ile vâkıf, ben de Java GlassFish sunucusunu kullanarak Comet kurmak ve cometdaily.com abone olarak diğer çokça örnek bulduk



9

Aşağıda Inform8 Web için geliştirdiğim uzun bir anket çözümü var. Temel olarak sınıfı geçersiz kılar ve loadData yöntemini uygularsınız. LoadData bir değer döndürdüğünde veya işlem zaman aşımına uğradığında sonucu yazdırır ve geri döner.

Betiğinizin işlenmesi 30 saniyeden uzun sürebilirse, set_time_limit () çağrısını daha uzun bir şeye değiştirmeniz gerekebilir.

Apache 2.0 lisansı. En son sürüm github https://github.com/ryanhend/Inform8/blob/master/Inform8-web/src/config/lib/Inform8/longpoll/LongPoller.php

Ryan

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

Kod için teşekkürler, dbr . Çizgi etrafında long_poller.htm içinde sadece küçük bir yazım hatası

1000 /* ..after 1 seconds */

Bence olmalı

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

çalışması için.

İlgilenenler için bir Django eşdeğerini denedim. Yeni bir Django projesi başlatın , diyelim ki , uzun oylama için :

django-admin.py startproject lp

Uygulamayı çağırın msgsrvMesaj sunucusu için :

python manage.py startapp msgsrv

Şablon olması için settings.py dosyasına aşağıdaki satırları ekleyin dizinine :

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

URL kalıplarınızı urls.py'de tanımlayın şu şekilde :

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'}),
)

Ve msgsrv / views.py görünmelidir:

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

Son olarak, şablonlar / long_poller.htm , yazım hatası düzeltilerek yukarıdakiyle aynı olmalıdır. Bu yardımcı olur umarım.


Aslında, "15000"sözdizimi hatasıdır. setTimeout, ikinci parametresi olarak bir tamsayıyı alır.
Andrew Hedges

Bu cevabın işe ihtiyacı var. Bir veya daha fazla yorumun ve ayrı bir cevabın veya cevapların sonucudur.
Brian Webster

8

Bu, PHP'nin çok kötü bir seçim olduğu senaryolardan biridir. Daha önce de belirtildiği gibi, tüm Apache çalışanlarınızı böyle bir şey yaparak çok hızlı bir şekilde bağlayabilirsiniz. PHP başlatma, yürütme, durdurma için tasarlanmıştır. Başlatmak, beklemek ... yürütmek, durdurmak için tasarlanmamıştır. Sunucunuzu çok hızlı bir şekilde batacak ve inanılmaz ölçeklendirme sorunlarınız olduğunu göreceksiniz.

Bununla birlikte, bunu PHP ile yapmaya devam edebilir ve nginx HttpPushStreamModule kullanarak sunucunuzu öldürmemesini sağlayabilirsiniz: http://wiki.nginx.org/HttpPushStreamModule

Nginx'i Apache'nin (veya başka bir şeyin) önüne kuruyorsunuz ve eşzamanlı bağlantıları açık tutmaya özen göstereceksiniz. Sadece bir arka plan işiyle yapabileceğiniz dahili bir adrese veri göndererek veya sadece yeni istekler geldiğinde bekleyen insanlara iletilerin gönderilmesini sağlayarak yükü yanıtlarsınız. Bu, PHP işlemlerinin uzun yoklama sırasında açık oturmasını önler.

Bu PHP'ye özel değildir ve herhangi bir arka uç diliyle nginx kullanılarak yapılabilir. Eşzamanlı açık bağlantı yükü Node.js'ye eşittir, bu nedenle en büyük güç, böyle bir şey için sizi İHTİYAÇ Düğümünden çıkarmasıdır.

Pek çok insanın uzun oylamayı başarmak için diğer dil kütüphanelerinden bahsettiğini görüyorsunuz ve bunun iyi bir nedeni var. PHP doğal olarak bu tür davranışlar için iyi inşa edilmemiştir.


Bu bir Apache sorunu mu yoksa PHP sorunu mu? PHP kodum doğrudan nginx veya lighttpd üzerinde çalıştırılırsa uzun yoklama ile ilgili sorunlar yaşar mıyım?
David

Daha az PHP sorunu ve daha çok PHP kötüye kullanımı. Her istek üzerine PHP, komut dosyasını sıfırdan çalıştırır, gerektiğinde kitaplıkları yükler, kodunu çalıştırır ve daha sonra istekte başlayan her şeyi toplarken çöpü kapatır. Yıllar geçtikçe PHP'de geç statik bağlamalar, tembel yükleme, disk G / Ç vb. Kaldırmak için bellek bayt kodu önbellekleri gibi etkiyi en aza indirmek için birçok değişiklik yapıldı. olabildiğince. Bir kez yüklenecek / önyükleme yapacak ve istek için bir iş parçacığı açacak diller uzun yoklama için çok daha uygundur.
brightball

Ancak soruyu cevaplamak için, evet, Apache veya başka bir şey kullanıyor olmanıza bakılmaksızın sorunu yaşarsınız. PHP tam da böyle çalışır. Bilinen bir maksimum trafik yüküne sahip olacaksanız PHP'nin iyi olacağını söylemek için bunu değiştirmeliyim. Sadece birkaç bağlantı olduğu için sorun olmayan PHP kullanan gömülü sistemler gördüm. Potansiyel olarak bir şirket intranetinde bu da fena olabilir. Halka açık uygulamalar için, trafik arttıkça sunucularınızı kesinlikle öldüreceksiniz.
brightball

4

Neden uzun yoklama yerine web soketlerini düşünmüyorsunuz? Çok verimli ve kurulumu kolaydır. Ancak, yalnızca modern tarayıcılarda desteklenirler. İşte hızlı bir referans .


Websockets her yerde (muhtemelen gelecek yıllar için değil) uygulandığında, bu tür bir uygulama için standart olacağını düşünüyorum. Ne yazık ki şimdilik, üretim uygulamaları için onlara güvenemeyiz.
Richard

3
@Richard Ancak Socket.IO gibi otomatik geri dönüş taşımacılığı sağlayan, IE 6'ya kadar web soketi benzeri işlevsellik sağlayan bir şey kullanabilirsiniz.
Brad



2

Libevent ile oluşturulmuş bir C1000K C ++ kuyruklu yıldız sunucusu olan icomet'i ( https://github.com/ideawu/icomet ) deneyebilirsiniz. icomet ayrıca bir JavaScript kütüphanesi sağlar, kullanımı kolaydır.

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, Safari (iOS, Mac), IE'ler (Windows), Firefox, Chrome vb. dahil çok çeşitli Tarayıcıları ve İşletim Sistemlerini destekler.


0

En Basit DüğümJS

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

Orta responsekatman yazılımında alacağınız exmaple için Express'te üretim bilimi senaryosu . Yapmanız gerekeni yapıyor musunuz, Harita için uzun sorgulanmış yöntemlerin tümünü veya diğer akışları görebilen bir şeyi kapsayabilir ve <Response> response.end()hazır olduğunuzda çağırabilirsiniz . Uzun yoklamalı bağlantılar hakkında özel bir şey yoktur. Dinlenme, normalde uygulamanızı nasıl yapılandırdığınızdır.

Kapsam belirleyerek ne demek istediğimi bilmiyorsanız, bu size fikir vermeli

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

Gördüğünüz gibi, tüm bağlantılara gerçekten yanıt verebilirsiniz, bir, istediğinizi yapın. Orada idsen api ve ara haritası ve erişim donanımları kullanabilmek mümkün olmalıdır yani her istek için.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.