Les événements envoyés par le serveur sont un composant de la spécification HTML 5 et peuvent être utilisés pour transmettre des données du serveur au navigateur en temps réel. Par rapport aux technologies COMET et WebSocket similaires, les événements push du serveur sont plus simples à utiliser et nécessitent moins de modifications côté serveur. Pour certains types d’applications, les événements push du serveur constituent la meilleure option.
WebSocket
Avant d'introduire les événements push du serveur HTML 5, introduisez d'abord certaines des technologies push de données côté serveur mentionnées ci-dessus. Le premier est WebSocket. La spécification WebSocket est une partie importante de HTML 5 et a été prise en charge par de nombreux navigateurs grand public. Il existe également de nombreuses applications développées sur la base de WebSocket. Comme son nom l'indique, WebSocket utilise une connexion socket, basée sur le protocole TCP. Après avoir utilisé WebSocket, une connexion socket est effectivement établie entre le serveur et le navigateur, permettant une transmission de données bidirectionnelle. WebSocket est très puissant et flexible à utiliser et peut être appliqué à différents scénarios. Cependant, la technologie WebSocket est également relativement complexe, comprenant des implémentations côté serveur et côté navigateur qui sont différentes des applications Web générales.
Sondage
En plus de WebSocket, d'autres méthodes d'implémentation sont basées sur le protocole HTTP pour obtenir un effet push en temps réel. La première méthode est une simple interrogation, c'est-à-dire que le navigateur envoie périodiquement des requêtes au serveur pour vérifier s'il y a une mise à jour des données. Cette approche est relativement simple et peut résoudre le problème dans une certaine mesure. Cependant, l’intervalle d’interrogation doit être soigneusement étudié. Si l'intervalle d'interrogation est trop long, l'utilisateur ne pourra pas recevoir les données mises à jour à temps ; si l'intervalle d'interrogation est trop court, cela entraînera un trop grand nombre de requêtes de requête et augmentera la charge sur le serveur.
Inconvénients :
1 : L'interrogation est initiée par le client, le serveur ne peut donc pas déterminer si le contenu que je souhaite diffuser a expiré, car il m'est difficile de déterminer si une certaine information a été transmis à tous les clients, le serveur doit alors mettre en cache une grande quantité de données. Si les données sont stockées dans la base de données, celle-ci doit être interrogée à chaque requête, ce qui constitue un défi majeur tant pour la conception de la base de données que du système.
2 : La fréquence des requêtes est trop élevée. Chaque paquet de requête contient les mêmes données. Ce n'est peut-être pas un gros problème pour les PC, mais pour les clients mobiles, ce n'est probablement pas le meilleur. solution. Surtout lorsqu'il s'agit de porter des jugements sur les autorisations, la logique et l'efficacité du serveur réduiront également l'expérience utilisateur.
COMET
La technologie COMET améliore les défauts des interrogations simples et utilise des interrogations longues. Dans la méthode d'interrogation longue, le serveur maintiendra la connexion ouverte pendant un certain temps lors de chaque requête, au lieu de la fermer immédiatement une fois la réponse terminée. L'avantage est que pendant la période où la connexion est ouverte, les mises à jour des données générées par le serveur peuvent être renvoyées au navigateur en temps opportun. Lorsque la connexion longue précédente est fermée, le navigateur ouvrira immédiatement une nouvelle connexion longue pour poursuivre la demande. Cependant, la mise en œuvre de la technologie COMET nécessite le support de bibliothèques tierces aussi bien côté serveur que côté navigateur.
De nos jours, la plupart des Web Apps ont Ajax, qui ressemble à ceci :
Comparaison complète des 4 technologies différentes citées ci-dessus, simple Les sondages ne sont pas recommandés en raison de leurs défauts inhérents. La technologie COMET ne fait pas partie du standard HTML 5 et son utilisation n'est pas recommandée dans une perspective de conformité au standard. La spécification WebSocket et la technologie Server Push sont toutes deux des composants de la norme HTML 5. Elles offrent une prise en charge native dans les navigateurs grand public et sont recommandées. Cependant, la spécification WebSocket est plus complexe et convient aux scénarios nécessitant une communication de données bidirectionnelle complexe. Pour les scénarios simples de transmission de données de serveur, l'utilisation d'événements de transmission de données de serveur est suffisante.
Le push basé sur les données est comme ceci Lorsque la source de données contient de nouvelles données, elles sont immédiatement envoyées au client sans attendre la demande du client. Ces nouvelles données peuvent être les dernières nouvelles, les dernières cotations boursières, les messages de chat d'amis, les prévisions météorologiques, etc.
Les fonctions d'extraction et de transmission de données sont les mêmes, les utilisateurs obtiennent de nouvelles données. Mais le transfert de données présente certains avantages. Vous avez peut-être entendu dire que Comet, Ajax push, reverse Ajax, HTTP streaming, WebSockets et SSE sont des technologies différentes. Le plus gros avantage est probablement la faible latence. SSE est utilisé par les applications Web pour actualiser les données sans nécessiter aucune action de la part de l'utilisateur.
WebSockets est une technologie plus complexe pour implémenter le serveur, mais il s'agit d'un véritable socket full-duplex. Le serveur peut transmettre des données au client, et le client peut également renvoyer des données au serveur. SSE fonctionne avec le protocole HTTP/HTTPS et prend en charge les serveurs proxy et les technologies d'authentification. SSE est un protocole texte et vous pouvez facilement le déboguer. Si vous devez envoyer principalement des données binaires du serveur au client, WebSocket est un meilleur choix.
Heureusement, Html5 nous offre un moyen : Server-Sent Events contient le nouvel élément HTML EventSource et le nouveau type MIME text/event-stream pour répondre à mes besoins.
L'API d'événement envoyé par le serveur est l'interface EventSource. Lorsque vous créez un nouvel objet EventSource, vous pouvez spécifier un URI qui accepte les événements :
var evtSource = new EventSource("ssedemo.php");
<!DOCTYPE html><html><head> <title>sever Sent Event实例1</title></head><body> <h2>sever Sent Event实例1</h2> <p id="result"></p> <script type="text/javascript"> var result = document.getElementById('result'); if (typeof (EventSource) !== 'undefined') { //创建事件源 var source = new EventSource('test.php'); //监听事件源发送过来的数据 source.onmessage = function(event){ result.innerHTML +=event.data +'<br>'; } }else{ result.innerHTML += "您的浏览器不支持server sent Event"; } </script></body></html>
<?php //指定发送事件流的MIME为text/event-stream header('Content-Type:text/event-stream'); //不缓存服务端发送的数据 header('Cache-Control:no-cache'); //指定服务器发送的事件名 echo "event:test\n\n"; // 定义服务器向客户端发送的数据 echo "data:服务器当前时间为:".date('Y-m-d H:i:s')."\n\n"; //向客户端发送数据流 flush(); ?>
"data:contentnn", sinon. . .
Champ
événement Type d'événement si ce champ est spécifié, il est reçu sur le client lors d'un message. est reçu, un événement sera déclenché sur l'objet EventSource actuel. Le type d'événement est la valeur du champ. Vous pouvez utiliser la méthode addEventListener() pour écouter tout type d'événement nommé sur l'objet EventSource actuel. n'a pas de champ d'événement, la fonction de traitement d'événement sur l'attribut onmessage sera déclenchée
data Le champ de données du message. Le message contient plusieurs champs de données, puis le client utilisera des nouvelles lignes pour les concaténer en une chaîne car la valeur du champ
id Event ID deviendra l'ID d'événement. partie interne de l'objet EventSource actuel La valeur d'attribut de l'attribut "Last Event ID".
retry Une valeur entière qui spécifie l'heure de reconnexion ( en millisecondes), si si la valeur du champ n'est pas un entier, elle sera ignorée
À l'exception des noms de champs spécifiés ci-dessus, tous les autres noms de champs seront ignorés au client toutes les 3 secondes, tandis que FF le transmettra. toutes les 5 secondes.
Objet EventSource Événements standards fournis
<!DOCTYPE html><html><head> <title>sever Sent Event实例1</title></head><body> <h2>sever Sent Event实例1</h2> <button onclick="closeCnt()">断开连接</button> <p id="result"></p> <script type="text/javascript"> var result = document.getElementById('result'); if (typeof (EventSource) !== 'undefined') { //创建事件源 var source = new EventSource('test.php'); //监听事件源发送过来的数据 source.onmessage = function(event){ result.innerHTML +=event.data +'<br>'; } source.onopen = connectionOpen; source.onclose = connectionClose; function connectionOpen(){ if (source.readyState == 0) { result.innerHTML +='未建立连接<br>'; } if (source.readyState == 1) { result.innerHTML +='连接成功<br>'; } } function connectionClose(){ result.innerHTML += "关闭连接,readyState属性值为:" + source.readyState + '<br>'; } function closeCnt(){ source.close(); result.innerHTML += "断开连接,readyState属性值为:" + source.readyState + '<br>'; } }else{ result.innerHTML += "您的浏览器不支持server sent Event"; } </script></body></html>
在指定 URL 创建出 EventSource 对象之后,可以通过 onmessage 和 addEventListener 方法来添加事件处理方法。当服务器端有新的事件产生,相应的事件处理方法会被调用。EventSource 对象的 onmessage 属性的作用类似于 addEventListener( ‘ message ’ ),不过 onmessage 属性只支持一个事件处理方法。
<!DOCTYPE html><html><head> <title>sever Sent Event实例1</title></head><body> <h2>sever Sent Event实例1</h2> <p id="result"></p> <script type="text/javascript"> var result = document.getElementById('result'); if (typeof (EventSource) !== 'undefined') { //创建事件源 var source = new EventSource('test.php'); //自定义事件源发送过来的数据,事件名和php中事件名对应 source.addEventListener('myevent', 'updateRequests', false); // source.onmessage = function() { // result.innerHTML = event.data + '<br>'; // } function updateRequests(event){ result.innerHTML = event.data + '<br>'; } }else{ result.innerHTML += "您的浏览器不支持server sent Event"; } </script></body></html>
<?php //指定发送事件流的MIME为text/event-stream header('Content-Type:text/event-stream'); //不缓存服务端发送的数据 header('Cache-Control:no-cache'); //指定服务器发送的事件名 echo "event:myevent\n\n"; // 定义服务器向客户端发送的数据 echo "data:服务器当前时间为:".date('Y-m-d H:i:s')."\n\n"; //向客户端发送数据流 flush(); ?>
前端是HTML5,后端可以是PHP, JSP, Node.js, Asp.net等应用。
服务器推送事件(Server-sent Events)是 HTML 5 规范中的一个组成部分,可以用来从服务端实时推送数据到浏览器端。相对于与之类似的 COMET 和 WebSocket 技术来说,服务器推送事件的使用更简单,对服务器端的改动也比较小。对于某些类型的应用来说,服务器推送事件是最佳的选择。
WebSocket
在介绍 HTML 5 服务器推送事件之前,首先介绍一些上面提到的几种服务器端数据推送技术。第一种是 WebSocket。WebSocket 规范是 HTML 5 中的一个重要组成部分,已经被很多主流浏览器所支持,也有不少基于 WebSocket 开发的应用。正如名称所表示的一样,WebSocket 使用的是套接字连接,基于 TCP 协议。使用 WebSocket 之后,实际上在服务器端和浏览器之间建立一个套接字连接,可以进行双向的数据传输。WebSocket 的功能是很强大的,使用起来也灵活,可以适用于不同的场景。不过 WebSocket 技术也比较复杂,包括服务器端和浏览器端的实现都不同于一般的 Web 应用。
轮询
除了 WebSocket 之外,其他的实现方式是基于 HTTP 协议来达到实时推送的效果。第一种做法是简易轮询,即浏览器端定时向服务器端发出请求,来查询是否有数据更新。这种做法比较简单,可以在一定程度上解决问题。不过对于轮询的时间间隔需要进行仔细考虑。轮询的间隔过长,会导致用户不能及时接收到更新的数据;轮询的间隔过短,会导致查询请求过多,增加服务器端的负担。
缺点:
1:轮询是由客户端发起的,那么在服务端就不能判别我要推送的内容是否已经过期,因为我很难判断某个信息是否已经推送给全部的客户端,那么服务端就需要缓存大量的数据。如果数据保存在数据库,那么还要每次请求都需要查询数据库,这对数据库和系统设计都是一个很大的挑战。
2:请求的频率太高,每次的请求包中含有同样的数据,这对pc来说也许算不得什么,但是对于移动客户端来讲,这应该不是最佳的方案。尤其是遇到还要做权限判断的时候,那么服务端的逻辑和效率也会造成用户体验的降低。
COMET
COMET 技术改进了简易轮询的缺点,使用的是长轮询。长轮询的方式在每次请求时,服务器端会保持该连接在一段时间内处于打开状态,而不是在响应完成之后就立即关闭。这样做的好处是在连接处于打开状态的时间段内,服务器端产生的数据更新可以被及时地返回给浏览器。当上一个长连接关闭之后,浏览器会立即打开一个新的长连接来继续请求。不过 COMET 技术的实现在服务器端和浏览器端都需要第三方库的支持。
现在Web App中,大都有Ajax,是这样子:
综合比较上面提到的 4 种不同的技术,简易轮询由于其本身的缺陷,并不推荐使用。COMET 技术并不是 HTML 5 标准的一部分,从兼容标准的角度出发,也不推荐使用。WebSocket 规范和服务器推送技术都是 HTML 5 标准的组成部分,在主流浏览器上都提供了原生的支持,是推荐使用的。不过 WebSocket 规范更加复杂一些,适用于需要进行复杂双向数据通讯的场景。对于简单的服务器数据推送的场景,使用服务器推送事件就足够了。
基于数据推送是这样的,当数据源有新数据,它马上发送到客户端,不需要等待客户端请求。这些新数据可能是最新闻,最新股票行情,来自朋友的聊天信息,天气预报等。
数据拉与推的功能是一样的,用户拿到新数据。但数据推送有一些优势。 你可能听说过Comet, Ajax推送, 反向Ajax, HTTP流,WebSockets与SSE是不同的技术。可能最大的优势是低延迟。SSE用于web应用程序刷新数据,不需要用户做任何动作。
WebSockets est une technologie plus complexe pour implémenter le serveur, mais il s'agit d'un véritable socket full-duplex. Le serveur peut transmettre des données au client, et le client peut également renvoyer des données au serveur. SSE fonctionne avec le protocole HTTP/HTTPS et prend en charge les serveurs proxy et les technologies d'authentification. SSE est un protocole texte et vous pouvez facilement le déboguer. Si vous devez envoyer principalement des données binaires du serveur au client, WebSocket est un meilleur choix.
Heureusement, Html5 nous offre un moyen : Server-Sent Events contient le nouvel élément HTML EventSource et le nouveau type MIME text/event-stream pour répondre à mes besoins.
L'API d'événement envoyé par le serveur est l'interface EventSource. Lorsque vous créez un nouvel objet EventSource, vous pouvez spécifier un URI qui accepte les événements :
var evtSource = new EventSource("ssedemo.php");
<!DOCTYPE html><html><head> <title>sever Sent Event实例1</title></head><body> <h2>sever Sent Event实例1</h2> <p id="result"></p> <script type="text/javascript"> var result = document.getElementById('result'); if (typeof (EventSource) !== 'undefined') { //创建事件源 var source = new EventSource('test.php'); //监听事件源发送过来的数据 source.onmessage = function(event){ result.innerHTML +=event.data +'<br>'; } }else{ result.innerHTML += "您的浏览器不支持server sent Event"; } </script></body></html>
<?php //指定发送事件流的MIME为text/event-stream header('Content-Type:text/event-stream'); //不缓存服务端发送的数据 header('Cache-Control:no-cache'); //指定服务器发送的事件名 echo "event:test\n\n"; // 定义服务器向客户端发送的数据 echo "data:服务器当前时间为:".date('Y-m-d H:i:s')."\n\n"; //向客户端发送数据流 flush(); ?>
"data:contentnn", sinon. . .
Champ
événement Type d'événement si ce champ est spécifié, il est reçu sur le client lors d'un message. est reçu, un événement sera déclenché sur l'objet EventSource actuel. Le type d'événement est la valeur du champ. Vous pouvez utiliser la méthode addEventListener() pour écouter tout type d'événement nommé sur l'objet EventSource actuel. n'a pas de champ d'événement, la fonction de traitement d'événement sur l'attribut onmessage sera déclenchée
data Le champ de données du message. Le message contient plusieurs champs de données, puis le client utilisera des nouvelles lignes pour les concaténer en une chaîne car la valeur du champ
id Event ID deviendra l'ID d'événement. partie interne de l'objet EventSource actuel La valeur d'attribut de l'attribut "Last Event ID".
retry Une valeur entière qui spécifie l'heure de reconnexion ( en millisecondes), si si la valeur du champ n'est pas un entier, elle sera ignorée
À l'exception des noms de champs spécifiés ci-dessus, tous les autres noms de champs seront ignorés au client toutes les 3 secondes, tandis que FF le transmettra. toutes les 5 secondes.
Objet EventSource Événements standards fournis
<!DOCTYPE html><html><head> <title>sever Sent Event实例1</title></head><body> <h2>sever Sent Event实例1</h2> <button onclick="closeCnt()">断开连接</button> <p id="result"></p> <script type="text/javascript"> var result = document.getElementById('result'); if (typeof (EventSource) !== 'undefined') { //创建事件源 var source = new EventSource('test.php'); //监听事件源发送过来的数据 source.onmessage = function(event){ result.innerHTML +=event.data +'<br>'; } source.onopen = connectionOpen; source.onclose = connectionClose; function connectionOpen(){ if (source.readyState == 0) { result.innerHTML +='未建立连接<br>'; } if (source.readyState == 1) { result.innerHTML +='连接成功<br>'; } } function connectionClose(){ result.innerHTML += "关闭连接,readyState属性值为:" + source.readyState + '<br>'; } function closeCnt(){ source.close(); result.innerHTML += "断开连接,readyState属性值为:" + source.readyState + '<br>'; } }else{ result.innerHTML += "您的浏览器不支持server sent Event"; } </script></body></html>
在指定 URL 创建出 EventSource 对象之后,可以通过 onmessage 和 addEventListener 方法来添加事件处理方法。当服务器端有新的事件产生,相应的事件处理方法会被调用。EventSource 对象的 onmessage 属性的作用类似于 addEventListener( ‘ message ’ ),不过 onmessage 属性只支持一个事件处理方法。
<!DOCTYPE html><html><head> <title>sever Sent Event实例1</title></head><body> <h2>sever Sent Event实例1</h2> <p id="result"></p> <script type="text/javascript"> var result = document.getElementById('result'); if (typeof (EventSource) !== 'undefined') { //创建事件源 var source = new EventSource('test.php'); //自定义事件源发送过来的数据,事件名和php中事件名对应 source.addEventListener('myevent', 'updateRequests', false); // source.onmessage = function() { // result.innerHTML = event.data + '<br>'; // } function updateRequests(event){ result.innerHTML = event.data + '<br>'; } }else{ result.innerHTML += "您的浏览器不支持server sent Event"; } </script></body></html>
<?php //指定发送事件流的MIME为text/event-stream header('Content-Type:text/event-stream'); //不缓存服务端发送的数据 header('Cache-Control:no-cache'); //指定服务器发送的事件名 echo "event:myevent\n\n"; // 定义服务器向客户端发送的数据 echo "data:服务器当前时间为:".date('Y-m-d H:i:s')."\n\n"; //向客户端发送数据流 flush(); ?>
前端是HTML5,后端可以是PHP, JSP, Node.js, Asp.net等应用。
以上就是Html5 服务端推送 Server-Sent Event的内容,更多相关内容请关注PHP中文网(www.php.cn)!