Bagaimana cara menerapkan "Polling Panjang" dasar?

776

Saya dapat menemukan banyak informasi tentang cara kerja Polling Panjang (Misalnya, ini , dan ini ), tetapi tidak ada contoh sederhana tentang bagaimana menerapkan ini dalam kode.

Yang bisa saya temukan adalah cometd , yang bergantung pada kerangka Dojo JS, dan sistem server yang cukup kompleks ..

Pada dasarnya, bagaimana saya akan menggunakan Apache untuk melayani permintaan, dan bagaimana saya akan menulis skrip sederhana (katakanlah, dalam PHP) yang akan "polling panjang" server untuk pesan baru?

Contohnya tidak harus skala, aman atau lengkap, hanya perlu bekerja!

dbr
sumber

Jawaban:

512

Ini lebih sederhana daripada yang saya pikir sebelumnya. Pada dasarnya Anda memiliki halaman yang tidak melakukan apa-apa, sampai data yang ingin Anda kirim tersedia (misalnya, pesan baru tiba).

Berikut ini adalah contoh yang sangat mendasar, yang mengirimkan string sederhana setelah 2-10 detik. 1 dalam 3 peluang untuk mengembalikan kesalahan 404 (untuk menunjukkan penanganan kesalahan dalam contoh Javascript mendatang)

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

Catatan: Dengan situs nyata, menjalankan ini di server web biasa seperti Apache akan dengan cepat mengikat semua "utas pekerja" dan membiarkannya tidak dapat menanggapi permintaan lainnya .. Ada beberapa cara untuk mengatasi ini, tetapi disarankan untuk menulis "server jajak pendapat panjang" dalam sesuatu seperti Python yang dipelintir , yang tidak bergantung pada satu utas per permintaan. cometD adalah yang populer (yang tersedia dalam beberapa bahasa), dan Tornado adalah kerangka kerja baru yang dibuat khusus untuk tugas-tugas semacam itu (ini dibangun untuk kode polling panjang FriendFeed) ... tetapi sebagai contoh sederhana, Apache lebih dari cukup ! Script ini dapat dengan mudah ditulis dalam bahasa apa pun (saya memilih Apache / PHP karena sangat umum, dan kebetulan saya menjalankannya secara lokal)

Kemudian, dalam Javascript, Anda meminta file di atas ( msg_srv.php), dan menunggu jawaban. Ketika Anda mendapatkan satu, Anda bertindak berdasarkan data. Kemudian Anda meminta file dan menunggu lagi, bertindak berdasarkan data (dan ulangi)

Berikut ini adalah contoh halaman seperti itu .. Ketika halaman dimuat, itu mengirimkan permintaan awal untuk msgsrv.phpfile .. Jika berhasil, kami menambahkan pesan ke #messagesdiv, maka setelah 1 detik kami memanggil fungsi waitForMsg lagi, yang memicu menunggu.

1 detik setTimeout()adalah pembatas laju yang sangat mendasar, berfungsi dengan baik tanpa ini, tetapi jika msgsrv.php selalu kembali secara instan (dengan kesalahan sintaks, misalnya) - Anda membanjiri peramban dan dapat membeku dengan cepat. Ini lebih baik dilakukan memeriksa apakah file tersebut berisi respons JSON yang valid, dan / atau menjaga agar total permintaan per menit / detik tetap berjalan, dan menjeda dengan tepat.

Jika halaman kesalahan, itu menambahkan kesalahan ke #messagesdiv, menunggu 15 detik dan kemudian mencoba lagi (identik dengan bagaimana kita menunggu 1 detik setelah setiap pesan)

Yang menyenangkan tentang pendekatan ini adalah sangat ulet. Jika koneksi internet klien mati, koneksi akan habis, kemudian coba dan sambungkan kembali - ini melekat dalam berapa lama polling bekerja, tidak diperlukan penanganan kesalahan yang rumit

Bagaimanapun, long_poller.htmkodenya, menggunakan kerangka 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>
dbr
sumber
7
Tidak bisakah beberapa pesan lolos menggunakan ide ini? Dalam 1 detik waktu habis, katakanlah 1000 pesan obrolan telah dikirim, bagaimana server tahu untuk mengirim 1000 pesan khusus ke klien itu?
DevDevDev
15
Mungkin. Ini adalah contoh yang sangat sederhana, untuk mendemonstrasikan konsep .. Untuk melakukan ini dengan lebih baik Anda perlu kode sisi server yang lebih rumit, di mana ia akan menyimpan 1000 pesan untuk klien tertentu itu, dan mengirimkannya dalam satu potongan. Anda juga dapat mengurangi waktu tunggu waitForMsg dengan aman
dbr
21
nodejs adalah solusi sisi server yang sangat baik untuk permintaan polling panjang, dengan keuntungan tambahan (lebih dari Twisted) yang Anda dapat menulis kode server dalam Javascript juga.
Husky
8
Ini hanyalah koneksi AJAX berulang ke server dengan interval 1 detik. Ini tidak ada hubungannya dengan "polling panjang". Polling yang panjang harus menjaga koneksi tetap hidup, selama batas waktu klien habis.
Deele
6
pertanyaannya adalah bukan apa yang dilakukan skrip PHP asli sleep(rand(2,10));? untuk tidak melakukan apa pun, polling database setiap 100 milidetik? kapan itu memutuskan untuk mati?
Luis Siquot
41

Saya punya contoh obrolan yang sangat sederhana sebagai bagian dari slosh .

Edit : (karena semua orang menempelkan kode mereka di sini)

Ini adalah obrolan multi-pengguna berbasis JSON lengkap menggunakan polling panjang dan slosh . Ini adalah demo cara melakukan panggilan, jadi silakan abaikan masalah XSS. Tidak ada yang harus menyebarkan ini tanpa membersihkannya terlebih dahulu.

Perhatikan bahwa klien selalu memiliki koneksi ke server, dan segera setelah ada yang mengirim pesan, semua orang akan melihatnya secara langsung.

<?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 <[email protected]> -->
<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>
Dustin
sumber
1
Bolehkah saya tahu bagaimana ini selalu terhubung? Maaf jika saya meminta sesuatu yang konyol, tetapi saya ingin tahu itu.
Rocky Singh
4
Ia melakukan HTTP GET dan server memblokir GET sampai ada data yang tersedia. Ketika data masuk ke server, server mengembalikan data ke klien, mengantri apa pun yang mungkin masuk dan kemudian klien menghubungkan kembali dan mengambil pesan yang hilang jika ada, jika tidak, blok lagi.
Dustin
4
Mungkin tidak jelas pada awalnya, tetapi hal yang bertanggung jawab untuk 'selalu terhubung negara' adalah ajaxStop dengan getNewCommentscallback di sana, jadi itu hanya menembakkannya pada akhir setiap permintaan ajax tanpa henti
botak
32

Tornado dirancang untuk polling panjang, dan menyertakan aplikasi obrolan yang sangat minimal (beberapa ratus baris Python) di / example / chatdemo , termasuk kode server dan kode klien JS. Ini berfungsi seperti ini:

  • Klien menggunakan JS untuk meminta pembaruan sejak (jumlah pesan terakhir), server URLHandler menerima ini dan menambahkan panggilan balik untuk menanggapi klien ke antrian.

  • Ketika server mendapatkan pesan baru, acara onmessage menyala, loop melalui callback, dan mengirim pesan.

  • JS sisi klien menerima pesan, menambahkannya ke halaman, lalu meminta pembaruan sejak ID pesan baru ini.

mikemaccana
sumber
25

Saya pikir klien terlihat seperti permintaan AJAX asinkron normal, tetapi Anda mengharapkannya untuk "lama" untuk kembali.

Server kemudian terlihat seperti ini.

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

outputNewData();

Jadi, permintaan AJAX masuk ke server, mungkin termasuk stempel waktu kapan terakhir diperbarui sehingga Anda hasNewData()tahu data apa yang sudah Anda dapatkan. Server kemudian duduk dalam loop tidur sampai data baru tersedia. Sementara itu, permintaan AJAX Anda masih terhubung, hanya menunggu di sana menunggu data. Akhirnya, ketika data baru tersedia, server memberikannya ke permintaan AJAX Anda dan menutup koneksi.

Greg
sumber
10
Ini adalah penantian sibuk yang memblokir utas Anda saat ini. Itu tidak berskala sama sekali.
Wouter Lievens
10
Tidak, tidur bukan menunggu sibuk. Dan inti dari "menunggu" adalah untuk memblokir utas Anda untuk sementara waktu. Mungkin maksudnya 50 milidetik (tidur (50.000)), bukan 50 mikrodetik! Tapi bagaimanapun, dengan setup Apache / PHP yang khas, apakah ada cara lain untuk melakukan ini?
Matt
Nah, dari prinsipnya, Anda tidak dapat membuat fungsi pemblokiran untuk pesan obrolan tanpa menunggu.
Tomáš Zato - Kembalikan Monica
Benar-benar hebat! Saya membangun fungsi rekursif di server untuk memeriksa data baru. Tapi apa produk terbaik untuk menggunakan polling panjang secara efisien? Saya menggunakan Apache normal dan server tidak merespons ketika saya membuka lebih dari 4/5 tab browser :( Mencari sesuatu untuk digunakan dengan PHP
modern
17

Berikut adalah beberapa kelas yang saya gunakan untuk polling panjang di C #. Pada dasarnya ada 6 kelas (lihat di bawah).

  1. Pengendali : Memproses tindakan yang diperlukan untuk membuat respons yang valid (operasi db dll.)
  2. Prosesor : Mengelola komunikasi asynch dengan halaman web (sendiri)
  3. IAsynchProcessor : Layanan memproses instance yang mengimplementasikan antarmuka ini
  4. Sevice : Memproses objek permintaan yang mengimplementasikan IAsynchProcessor
  5. Permintaan : Pembungkus IAsynchProcessor yang berisi respons Anda (objek)
  6. Respons : Berisi objek atau bidang khusus
Tahanan NOL
sumber
2
Oke ... jadi MENGAPA ini ditolak? Kelas-kelas ini memang contoh sah dari polling panjang.
Tahanan NOL
Polling panjang sebenarnya bukan (hanya) praktik meningkatkan interval ketika Anda melakukan polling normal (pada sumber daya). Ini adalah bagian dari pola yang lebih besar ... yang "agak" tunduk pada interpretasi ... tetapi hanya di area tertentu dari keseluruhan implementasi. Yang mengatakan ... kelas-kelas ini mengikuti pola kata! Jadi jika Anda memiliki alasan untuk memilih ini ... Saya benar-benar akan tertarik pada alasannya.
Tahanan NOL
Mungkin ditolak karena tidak langsung menjawab pertanyaan dari contoh kode sederhana. Tentu saja saya tidak memilihnya jadi saya hanya bisa menebak.
Andrew
16

Ini adalah screencast 5 menit yang bagus tentang cara melakukan polling panjang menggunakan PHP & jQuery: http://screenr.com/SNH

Kode sangat mirip dengan contoh dbr di atas.

Sean O
sumber
3
Saya pikir Anda hanya akan melihat ini sebagai pengantar polling panjang karena implementasi ini pasti akan membunuh server Anda dengan banyak pengguna secara bersamaan.
Alfred
Saya baru belajar tentang semua ini ... bagaimana bisa diandalkan, atau tidak, apakah itu dengan beberapa pengguna ... katakanlah 10 ngobrol kembali dan sebagainya?
Suatu hari
12

Berikut ini adalah contoh polling panjang sederhana dalam PHP oleh Erik Dubbelboer menggunakan Content-type: multipart/x-mixed-replaceheader:

<?

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

Dan ini adalah demo:

http://dubbelboer.com/multipart.php

Jasdeep Khalsa
sumber
11

Saya menggunakan ini untuk memahami Comet, saya juga mengatur Comet menggunakan server Java Glassfish dan menemukan banyak contoh lain dengan berlangganan ke cometdaily.com

adam
sumber
9

Di bawah ini adalah solusi polling panjang yang saya kembangkan untuk Web Inform8. Pada dasarnya Anda mengganti kelas dan menerapkan metode loadData. Ketika loadData mengembalikan nilai atau waktu operasi habis, itu akan mencetak hasilnya dan kembali.

Jika pemrosesan skrip Anda membutuhkan waktu lebih dari 30 detik, Anda mungkin perlu mengubah panggilan set_time_limit () menjadi sesuatu yang lebih lama.

Lisensi Apache 2.0. Versi terbaru di 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();

}
Ryan Henderson
sumber
8

Terima kasih untuk kodenya, dbr . Hanya kesalahan ketik kecil di long_poller.htm di sekitar baris

1000 /* ..after 1 seconds */

Saya pikir seharusnya begitu

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

agar bisa bekerja.

Bagi mereka yang tertarik, saya mencoba setara Django. Mulai proyek Django baru, katakan lp untuk polling panjang:

django-admin.py startproject lp

Panggil aplikasi msgsrv untuk server pesan:

python manage.py startapp msgsrv

Tambahkan baris berikut ke settings.py untuk memiliki direktori template :

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

Tetapkan pola URL Anda di urls.py seperti:

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

Dan msgsrv / views.py akan terlihat seperti:

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

Terakhir, templates / long_poller.htm harus sama seperti di atas dengan kesalahan ketik diperbaiki. Semoga ini membantu.

xoblau
sumber
Sebenarnya, itu "15000"adalah kesalahan sintaksis. setTimeout mengambil integer sebagai parameter ke-2.
Andrew Hedges
Jawaban ini perlu dikerjakan. Ini adalah puncak dari satu atau lebih komentar dan jawaban atau jawaban yang terpisah.
Brian Webster
8

Ini adalah salah satu skenario di mana PHP adalah pilihan yang sangat buruk. Seperti yang disebutkan sebelumnya, Anda dapat mengikat semua pekerja Apache Anda dengan sangat cepat melakukan sesuatu seperti ini. PHP dibangun untuk memulai, menjalankan, menghentikan. Itu tidak dibangun untuk memulai, tunggu ... jalankan, berhenti. Anda akan merobohkan server Anda dengan sangat cepat dan menemukan bahwa Anda memiliki masalah penskalaan yang luar biasa.

Yang mengatakan, Anda masih bisa melakukan ini dengan PHP dan tidak membunuh server Anda menggunakan nginx HttpPushStreamModule: http://wiki.nginx.org/HttpPushStreamModule

Anda mengatur nginx di depan Apache (atau apa pun yang lain) dan itu akan menjaga membuka koneksi bersamaan. Anda hanya merespons dengan payload dengan mengirim data ke alamat internal yang bisa Anda lakukan dengan pekerjaan latar belakang atau hanya mengirim pesan ke orang-orang yang menunggu kapan pun permintaan baru masuk. Ini menjaga proses PHP dari duduk terbuka selama pemungutan suara yang panjang.

Ini bukan eksklusif untuk PHP dan dapat dilakukan menggunakan nginx dengan bahasa backend apa pun. Beban koneksi terbuka bersamaan adalah sama dengan Node.js sehingga keuntungan terbesarnya adalah Anda keluar dari MEMBUTUHKAN Node untuk sesuatu seperti ini.

Anda melihat banyak orang menyebutkan perpustakaan bahasa lain untuk mencapai polling panjang dan itu dengan alasan yang bagus. PHP tidak dibangun dengan baik untuk jenis perilaku ini secara alami.

bola terang
sumber
Apakah ini masalah Apache atau masalah PHP? Apakah saya akan mengalami masalah dengan polling panjang jika kode PHP saya berjalan langsung di nginx atau lighttpd?
David
Ini bukan masalah PHP dan lebih banyak penyalahgunaan PHP. Pada setiap permintaan, PHP menjalankan skrip dari awal, memuat pustaka sesuai kebutuhan, menjalankan kode-nya dan kemudian mematikannya sementara pengumpulan sampah dimulai dari permintaan. Banyak modifikasi telah dibuat untuk PHP selama bertahun-tahun untuk meminimalkan dampak seperti binding statis terlambat, pemuatan malas, dalam cache bytecode memori untuk menghapus disk I / O, dll. Masalahnya tetap bahwa PHP dimaksudkan untuk memulai dan berhenti secepat mungkin. Bahasa yang akan memuat sekali / boot dan membuka utas untuk permintaan jauh lebih cocok untuk polling panjang.
brightball
Tetapi untuk menjawab pertanyaan, ya Anda akan mengalami masalah terlepas dari apakah Anda menggunakan Apache atau sesuatu yang lain. Hanya bagaimana PHP bekerja. Saya harus mengubah ini untuk mengatakan bahwa, jika Anda akan memiliki beban lalu lintas max yang dikenal PHP akan baik-baik saja. Saya telah melihat sistem embedded menggunakan PHP yang tidak memiliki masalah karena hanya ada beberapa koneksi. Berpotensi pada intranet perusahaan ini juga bisa lumayan. Untuk aplikasi yang menghadap publik, Anda benar-benar akan mematikan server Anda saat traffic bertambah.
brightball
4

Mengapa tidak mempertimbangkan soket web alih-alih polling panjang? Mereka jauh lebih efisien dan mudah diatur. Namun mereka hanya didukung di browser modern. Berikut ini adalah referensi cepat .

shasi kanth
sumber
Saya pikir begitu websockets diimplementasikan di mana-mana (mungkin tidak untuk tahun yang akan datang) mereka akan menjadi standar untuk aplikasi semacam ini. Sayangnya untuk saat ini, kami tidak dapat mengandalkan mereka untuk aplikasi produksi.
Richard
3
@ Richard Namun Anda dapat menggunakan sesuatu seperti Socket.IO yang menyediakan transport fallback otomatis, menyediakan fungsionalitas seperti web-socket sampai ke IE 6.
Brad
3

Grup WS-I menerbitkan sesuatu yang disebut "Reliable Secure Profile" yang memiliki implementasi Glass Fish dan .NET yang tampaknya beroperasi dengan baik.

Dengan sedikit keberuntungan ada implementasi Javascript di luar sana juga.

Ada juga implementasi Silverlight yang menggunakan HTTP Duplex. Anda dapat menghubungkan javascript ke objek Silverlight untuk mendapatkan panggilan balik ketika terjadi push.

Ada juga versi berbayar komersial .

goodguys_activate
sumber
2

Anda dapat mencoba icomet ( https://github.com/ideawu/icomet ), server komet C1000K C ++ yang dibuat dengan libevent. icomet juga menyediakan perpustakaan JavaScript, mudah digunakan sesederhana

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 mendukung berbagai Peramban dan OS, termasuk Safari (iOS, Mac), IEs (Windows), Firefox, Chrome, dll.

ideawu
sumber
0

NodeJS paling sederhana

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

Skenario produksi bijak di Express untuk exmaple yang akan Anda dapatkan responsedi middleware. Lakukan apa yang perlu Anda lakukan, dapat meringkas semua metode yang disurvei panjang untuk memetakan atau sesuatu (yang terlihat oleh aliran lain), dan memohon <Response> response.end()kapan pun Anda siap. Tidak ada yang istimewa tentang koneksi yang disurvei lama. Istirahat adalah bagaimana Anda biasanya menyusun aplikasi Anda.

Jika Anda tidak tahu apa yang saya maksud dengan membuang, ini harus memberi Anda ide

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

Seperti yang Anda lihat, Anda dapat benar-benar menanggapi semua koneksi, satu, lakukan apa pun yang Anda inginkan. Ada iduntuk setiap permintaan sehingga Anda harus dapat menggunakan peta dan mengakses panggilan api khusus.

sp3c1
sumber