Je suis sûr que chaque développeur Web a été confronté à la tâche de mise à jour rapide de l'interface utilisateur WEB par événement sur le back-end. Un exemple classique est le chat Web (si vous avez déjà écrit votre discussion Web Fire , vous pouvez sauter la lecture plus loin, vous savez probablement déjà tout ci-dessous).
Dans X5, je rencontre de telles tâches avec une fréquence enviable. Je dois dire que toutes sortes de chats, de chatbots et d'autres interactions de l'utilisateur final RealTime sont à la mode maintenant. Dans cet article, je souhaite résumer mon expérience en la matière et la partager avec les lecteurs de Habr.
Formulation du problème
Nous avons besoin d'un transport universel et efficace pour transmettre les événements de l'interface utilisateur WEB (navigateur de l'utilisateur) au serveur et retour du serveur vers l'interface utilisateur Web
Option 1 - ENQUÊTES PÉRIODIQUES
le moyen le plus simple et le plus inefficace
La signification est claire à partir du nom, du côté Client2 périodiquement, par exemple, une fois toutes les 1 seconde, des demandes telles que «Qu'y a-t-il?» Sont envoyées au serveur.
Cette approche présente deux inconvénients importants:
1-10 , , 1-10 , , , . , , 1-10 RPS.
— RealTime. , RealTime.
№2 -
long polling
№1, , , http-, (.. ), , , . , . , TimeOut
, , .
:
, .. http-, , , .
RealTime, .. , . , http . , , .. .
- №1.
№3 - SERVER SENT EVENT (SSE)
+ API
Server-Sent Events EventSource, . , EventSource . . , retry: ( )
!!! – !
, , , .
. , SSE , REST. http-. , , 1-10 ( ), - №1 :(, , , .
– . , . , , .
№4 - WEBSOCKET
WEBSOCKET SSE . SSE WEBSOCKET.
WEBSOCKET |
SSE |
: , |
: |
|
|
WebSocket |
HTTP |
FrontEnd <-> BackEnd Websocket Golang.
?
№1 - web- ( , app ..):
FrontEnd BackEnd (WS)
BackEnd (WS)
FrontEnd . (REST) (, )
3- .2, , .
2 - () , ,
BackEnd (WS)
FrontEnd (WS)
( )
:
(http://your_domain/ws)
Go «HUB»,
http http://your_domain/ws :
Go ( , ws )
http ws “CLIENT_CONNECTED”
// Message ...
type Message struct {
Type string `json:"type,omitempty"`
Event string `json:"event"`
Data string `json:"data"`
}
Event –
Data –
Type –
Type = publish, Data , Event
Type = broadcast, Data
Type = subscribe, , Event
Type = unsubscribe, , Event
-
. , MacBook Pro i5 8Gb 12K RPS
- . . .
SDK:
- , , .
– , SDK .
sdk :
<script src="http://localhost:9000/sdk/js" async onload="initEventTube()"></script>
localhost:9000 –
:
function initEventTube(){
var options={
connection:{
host:'localhost',
port:'9000'
}
}
var eventTube=new EventTube(options);
window.EventTube=eventTube;
window.EventTube.connect();
}
:
var self=this;
var subscriptionId=null;
window.EventTube.sub('YOUR_EVENT_NAME',function(data){
//
console.log(data);
}).then(function(subId){
//
subscriptionId = subId;
onsole.log('subId:',subId);
},function(err){
//
console.log(err);
});
:
window.EventTube.pub('YOUR_EVENT_NAME', 'YOUR_EVENT_DATA');
:
window.EventTube.unsub('YOUR_EVENT_NAME', 'OPTIONAL_SUB_ID');
. OPTIONAL_SUB_ID, , , . SUB_ID (. « »)
:
$ git clone git@github.com:colber/eventtube-server.git your_dir
$ cd your_dir
$ go run main.go
Docker
$ docker pull ptimofeev/eventtube:latest $ docker run --name eventtube --rm -p 9000:9000 ptimofeev/eventtube
: localhost:9000
$ git clone git@github.com:colber/eventtube-client.git your_dir
$ cd your_dir
$ yarn install
$ yarn serve
http://localhost:8080