서버에서 보낸 이벤트 및 php - 서버에서 이벤트를 트리거하는 항목은 무엇입니까?
모든.
HTML5 Rocks에는 Server-sent Events(SSE)에 관한 훌륭한 초보 튜토리얼이 준비되어 있습니다.
http://www.html5rocks.com/en/tutorials/eventsource/basics/
그러나 중요한 개념을 잘 모르겠습니다.서버에서 메시지를 보내는 이벤트가 발생하는 이유는 무엇입니까?
즉, HTML5 예에서는 서버가 타임스탬프를 한 번만 보냅니다.
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
예를 들어 Facebook 스타일의 "벽"이나 "주식 티켓"과 같이 데이터가 변경될 때마다 서버가 새로운 메시지를 클라이언트에 "푸시"하는 실용적인 예를 구축한다면, 어떻게 작동할까요?
다른 말로...PHP 스크립트에는 루프가 연속적으로 실행되어 데이터의 변경을 확인하고 루프가 발견될 때마다 메시지를 전송합니까? 그렇다면 언제 프로세스를 종료해야 하는지 어떻게 알 수 있습니까?
아니면 - PHP 스크립트는 단순히 메시지를 보낸 다음 종료합니까? (HTML5Rocks의 예에서와 같이)그렇다면 지속적인 업데이트를 받으려면 어떻게 해야 합니까?브라우저는 단순히 정기적으로 PHP 페이지를 폴링하고 있습니까?이 경우 - "서버 전송 이벤트"란 무엇입니까?이것은 정기적으로 PHP 페이지를 호출하기 위해 AJAX를 사용하는 JavaScript에서 setInterval 함수를 쓰는 것과 어떻게 다른가요?
미안 - 이것은 아마도 믿을 수 없을 정도로 순진한 질문일 것이다.하지만 내가 찾은 어떤 예도 이것을 명확하게 하지 못한다.
[업데이트]
제 질문이 표현이 서투른 것 같아서, 여기 몇 가지 해명이 있습니다.
예를 들어 애플 주식의 최신 가격을 표시하는 웹 페이지가 있다고 가정해 봅시다.
사용자가 처음 페이지를 열었을 때 페이지는 내 "스트림"의 URL을 사용하여 EventSource를 만듭니다.
var source = new EventSource('stream.php');
제 질문은 "stream.php"는 어떻게 작동합니까?
이렇게요?(모듈 코드):
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.
function sendMsg($msg) {
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
flush();
}
while (some condition) {
// check whether Apple's stock price has changed
// e.g., by querying a database, or calling a web service
// if it HAS changed, sendMsg with new price to client
// otherwise, do nothing (until next loop)
sleep (n) // wait n seconds until checking again
}
?>
즉, "stream.php"는 클라이언트가 "연결"되어 있는 한 열린 상태로 유지됩니까?
- '다'라는 요?stream.php
동시 사용자가 있는 경우?그렇다면 - 원격에서 실행 가능한가, 아니면 적절한 애플리케이션 구축 방법인가?그리고 당신은 언제 당신이 그 인스턴스를 끝낼 수 있는지 어떻게 알 수 있나요?stream.php
만약 그렇다면 PHP는 이런 종류의 서버에 적합한 기술이 아니라는 것이 저의 순진한 느낌입니다.하지만 지금까지 제가 본 모든 데모들은 PHP가 이것에 적합하다는 것을 암시합니다. 그래서 저는 너무 혼란스럽습니다.
서버에서 전송된 이벤트는 서버 측에서 클라이언트 측으로 실시간 업데이트하기 위한 것입니다.첫 번째 예에서는 서버로부터의 접속은 유지되지 않고 클라이언트는 3초마다 재접속을 시도하며 서버에서 송신된 이벤트는 ajax 폴링과 다르지 않습니다.
따라서 연결을 유지하려면 코드를 루프로 감싸고 업데이트를 지속적으로 확인해야 합니다.
PHP는 스레드 기반이며, 사용자가 연결되면 서버의 리소스가 부족해집니다.이 문제는 스크립트 실행 시간을 제어하여 해결할 수 있으며, 일정 시간(10분)을 초과하면 스크립트를 종료할 수 있습니다.EventSource
API가 자동으로 다시 연결되므로 지연은 허용 범위 내에 있습니다.
또, 서버 송신 이벤트에 대해서는, PHP 라이브러리를 봐 주세요.서버 송신 이벤트를 PHP로 실행하는 방법에 대해, 보다 간단하게 코드화할 수 있습니다.
"...'stream.flash'는 클라이언트가 '연결'되어 있는 한 열린 상태로 유지됩니까?"
네, 의사 코드는 합리적인 접근법입니다.
"그리고 언제 stream.php 인스턴스를 종료할 수 있는지 어떻게 알 수 있습니까?"
가장 일반적인 경우 사용자가 사이트를 떠날 때 발생합니다.(Apache는 닫힌 소켓을 인식하여 PHP 인스턴스를 중지합니다.)서버측에서 소켓을 닫을 수 있는 주요 시간은 당분간 데이터가 없을 것을 알고 있는 경우입니다.클라이언트에 보내는 마지막 메시지는 특정 시간에 돌아오라는 것입니다.예를 들어, 주식 스트리밍의 경우, 오후 8시에 접속을 종료하고, 고객에게 8시간 후에 돌아오라고 말할 수 있습니다(NASDAQ는 오전 4시부터 오후 8시까지 견적을 내고 있다고 가정).금요일 저녁에 당신은 그들에게 월요일 아침에 돌아오라고 말한다.(SSE에 관한 책이 곧 출간될 예정이며, 이 주제에 관한 몇 가지 섹션을 할애하고 있습니다.)
"...이러한 경우 PHP는 이런 종류의 서버에 적합한 기술이 아닙니다.하지만 지금까지 제가 본 모든 데모들은 PHP가 이것에 적합하다는 것을 암시하고 있기 때문에 매우 혼란스럽습니다.."
음, 사람들은 PHP가 일반적인 웹 사이트에 적합한 기술이 아니라고 주장합니다. 그리고 그들이 옳습니다: 만약 당신의 LAMP 스택 전체를 C++로 교체한다면 당신은 훨씬 적은 메모리와 CPU 사이클로 그것을 할 수 있습니다.그러나 그럼에도 불구하고 PHP는 대부분의 사이트를 정상적으로 가동하고 있다.익숙한 C-like 구문과 많은 라이브러리의 조합으로 웹 작업에 매우 생산적인 언어이며, 고용할 수 있는 PHP 프로그래머, 풍부한 서적 및 기타 자원, 그리고 일부 대규모 사용 사례(예: Facebook 및 Wikipedia)로 인해 관리자에게 위안이 되는 언어입니다.이것들은 기본적으로 스트리밍 테크놀로지로 PHP를 선택하는 것과 같은 이유입니다.
일반적인 설정은 PHP 인스턴스당 NASDAQ에 한 번 접속하는 것이 아닙니다.대신 NASDAQ에 단일 연결 또는 클러스터 내의 각 기계에서 NASDAQ에 단일 연결로 다른 프로세스를 수행할 수 있습니다.그러면 가격이 SQL/NoSQL 서버 또는 공유 메모리에 푸시됩니다.그런 다음 PHP는 공유 메모리(또는 데이터베이스)를 폴링하고 데이터를 푸시합니다.또는 데이터 수집 서버가 있고 각 PHP 인스턴스가 해당 서버에 대한 소켓 연결을 엽니다.데이터 수집 서버는 각 PHP 클라이언트에 업데이트를 수신하면 해당 데이터를 클라이언트에 푸시합니다.
Apache+ 사용의 주요 확장성 문제스트리밍용 PHP는 각 Apache 프로세스의 메모리입니다.하드웨어 메모리 제한에 도달하면 다른 머신을 클러스터에 추가하거나 Apache를 루프에서 분리하여 전용 HTTP 서버를 작성합니다.후자는 기존의 지식과 코드를 모두 재사용할 수 있도록 PHP로 할 수도 있고, 애플리케이션 전체를 다른 언어로 다시 쓸 수도 있습니다.순수한 개발자는 전용의 합리화된HTTP 서버를 C++로 작성합니다.내 안에 있는 매니저는 다른 상자를 추가할 것이다.
sse techink가 클라이언트에 지연 데이터를 2개씩 전송하는 것을 알게 되었습니다(클라이언트 페이지에서 풀링 데이터 techink를 되돌리는 것과 같습니다).Ajax pooling data.) 이 문제를 해결하기 위해 sseServer.php 페이지에서 다음과 같이 작성했습니다.
<?php
session_start();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data
require 'sse.php';
if ($_POST['message'] != ""){
$_SESSION['message'] = $_POST['message'];
$_SESSION['serverTime'] = time();
}
sendMsg($_SESSION['serverTime'], $_SESSION['message'] );
?>
및 sse.php는 다음과 같습니다.
<?php
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
?>
sseSer.php에서 세션을 시작하고 세션 변수를 사용하여 문제를 해결합니다.
경유로 sseServer. (Ajax 경유로 및 값 설정)variable message
를 「마다, 「업데이트」를 실시합니다.
이제 jQuery(script)에서 다음과 같은 작업을 수행합니다.첫 번째) 글로벌 변수 var timeStamp=0; 두 번째)를 선언합니다.다음 알고리즘을 사용합니다.
if(typeof(EventSource)!=="undefined"){
var source=new EventSource("sseServer.php");
source.onmessage=function(event)
if ((timeStamp!=event.lastEventId) && (timeStamp!=0)){
/* this is initialization */
timeStamp=event.lastEventId;
$.notify("Please refresh "+event.data, "info");
} else {
if (timeStamp==0){
timeStamp=event.lastEventId;
}
} /* fi */
} else {
document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
} /* fi */
에서 : 다음행 at:$.notify("Please refresh "+event.data, "info");
메시지를 처리할 수 있는 곳이 있어요
제 경우 jQuery 알림을 보내곤 했습니다.
sseServer.php는 "무한 루프"와 같은 작업을 수행하므로 POSIX PIPS 또는 DB 테이블을 사용하여 POST를 통해 "메시지"를 전달할 수 있습니다.
그때의 문제는 위의 코드가 모든 클라이언트에게 "메시지"를 보내는 것이 아니라 쌍(sseServer를 호출한 클라이언트)에게만 "메시지"를 보내는 것입니다.php는 모든 쌍에 대해 개별적으로 동작하기 때문에 "메시지"를 트리거하는 페이지에서 technik과 DB 업데이트를 변경하고 다음으로 sseServer를 변경합니다.대신 POST를 통해 메시지를 가져오려면 DB 테이블에서 메시지를 가져옵니다.
나에게 도움이 있었으면 좋겠어!
이것은 당신의 신청에 관한 구조적인 질문입니다.실시간 이벤트는 처음부터 생각하고 싶은 것이기 때문에 애플리케이션을 설계할 수 있습니다.랜덤하게 실행되는 어플리케이션을 작성했다면mysql(i)_query
스트링 쿼리를 사용하는 메서드에서는 어떤 종류의 매개체에도 전달되지 않습니다.그러면 어플리케이션의 대부분을 재작성하거나 서버측 폴링을 지속적으로 실행하는 것 외에 선택의 여지가 없습니다.
그러나 엔티티를 개체로 관리하고 중간 클래스를 통해 엔티티를 전달하면 해당 프로세스에 연결할 수 있습니다.다음 예를 보겠습니다.
<?php
class MyQueryManager {
public function find($myObject, $objectId) {
// Issue a select query against the database to get this object
}
public function save($myObject) {
// Issue a query that saves the object to the database
// Fire a new "save" event for the type of object passed to this method
}
public function delete($myObject) {
// Fire a "delete" event for the type of object
}
}
응용 프로그램에서 저장할 준비가 되면 다음을 수행합니다.
<?php
$someObject = $queryManager->find("MyObjectName", 1);
$someObject->setDateTimeUpdated(time());
$queryManager->save($someObject);
이것은 가장 우아한 예는 아니지만 적절한 구성 요소 역할을 해야 한다.이러한 이벤트의 트리거를 처리하기 위해 실제 지속성 계층에 연결할 수 있습니다.그러면 서버에 영향을 주지 않고 즉시(가능한 한 실시간으로) 얻을 수 있습니다(데이터베이스에 끊임없이 문의하여 변경 여부를 확인할 필요가 없기 때문입니다).
이 방법으로는 데이터베이스에 대한 수동 변경 내용을 확인할 수 없지만, 데이터베이스에 대해 빈도로 수동으로 작업을 수행하는 경우에는 다음 중 하나를 수행해야 합니다.
- 수동으로 변경해야 하는 문제를 해결합니다.
- 프로세스를 신속화하기 위한 도구를 구축하고 이러한 이벤트를 발생시킵니다.
기본적으로 PHP는 이러한 종류의 기술에는 적합하지 않습니다.네, 할 수는 있지만, 고부하에서는 큰일이 날 겁니다.우리는 웹소켓을 통해 수십 명의 사용자에게 주식교환 신호를 보내는 스톡서버를 운영하고 있습니다.그것에 php를 사용한다면...그럴 수도 있지만 집에서 만든 사이클은 악몽일 뿐이야모든 연결은 서버에서 개별 프로세스를 생성하거나 데이터베이스 연결을 처리해야 합니다.
nodejs 및 socket.io을 사용하면 됩니다.이 툴을 사용하면, 간단하게 기동해, 서버를 수일 이내에 가동할 수 있습니다.Nodejs에도 제한이 있지만 웹소켓(및 SSE) 연결은 현재 가장 강력한 기술입니다.
SSE는 보기만큼 좋지 않습니다.웹소켓의 유일한 장점은 패킷이 네이티브하게 gzip된다는 것입니다(ws는 gzip되지 않음). 단점은 SSE가 단측 접속이라는 것입니다.사용자가 서브스크립트에 다른 주식 기호를 추가하려면 Ajax 요청을 해야 합니다(원점 제어와 관련된 모든 문제를 포함하면 요청이 느려집니다).웹소켓에서는 클라이언트와 서버는 하나의 열린 연결로 양방향으로 통신하기 때문에 사용자가 거래 신호를 보내거나 견적을 신청하면 이미 열린 연결로 문자열을 보냅니다.그리고 빠르다.
언급URL : https://stackoverflow.com/questions/14564903/server-sent-events-and-php-what-triggers-events-on-the-server
'source' 카테고리의 다른 글
Java "? null을 확인하는 연산자 - 뭐죠? (Ternary가 아닙니다!) (0) | 2022.09.08 |
---|---|
jQuery에서 div를 "fadeOut" 및 "삭제"하는 방법은 무엇입니까? (0) | 2022.09.08 |
CSV 파일을 MySQL 테이블로 Import하는 방법 (0) | 2022.09.08 |
바이트 []에서 InputStream 또는 OutputStream으로 (0) | 2022.09.06 |
$_SERVER[``를 사용 가능HTTP_X_REQUESTED_WITH']가 PHP에 존재합니까? (0) | 2022.09.06 |