Livraison de messages en temps réel à l'avant

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. 1-10 , , 1-10 , , , . , , 1-10 RPS.





  2. — RealTime. , RealTime.









№2 -

long polling









№1, , , http-, (.. ), , , . , . , TimeOut









, , .





:





  1. , .. http-, , , .





  2. 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 ..):





  1. FrontEnd BackEnd (WS)





  2. BackEnd (WS)





  3. FrontEnd . (REST) (, )





3- .2, , .









2 - () , ,





  1. BackEnd (WS)





  2. FrontEnd (WS)





( )

:





  1. (http://your_domain/ws)





  2. Go «HUB»,









http http://your_domain/ws :





  1. Go ( , ws )





  2. 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









-

"Inscription à un événement"
« »





"Publication d'un événement"
« »
"Diffusion"
« »
"Se désabonner d'un événement"
« »





. , MacBook Pro i5 8Gb 12K RPS









- . . .









. js/sdk (6Kb) web-.









SDK:





  1. - , , .





  2. – , 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 (. « »)









:

Golang . Golang





$ 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












All Articles