Entrega de mensagens RealTime para a frente

Tenho certeza de que todo desenvolvedor web enfrentou a tarefa de atualização imediata da IU da WEB por evento no back-end. Um exemplo clássico é um bate-papo na web (se você já escreveu seu fogo web chat, você pode pular de ler mais, muito provavelmente você já sabe tudo abaixo).





No X5, encontro essas tarefas com uma frequência invejável. Devo dizer que todos os tipos de chats, chatbots e outras interações do usuário final do RealTime estão em alta agora. Neste artigo, quero resumir minha experiência neste assunto e compartilhá-la com os leitores de Habr.





Formulação do problema

Precisamos de um transporte universal e eficiente para entregar eventos da WEB UI (navegador do usuário) para o servidor e de volta do servidor para a WEB UI





Opção nº 1 - PESQUISAS PERIÓDICAS

a maneira mais fácil e ineficaz









O significado fica claro a partir do nome, do lado do Cliente2 periodicamente, por exemplo, uma vez a cada 1 segundo, solicitações como “O que há?” São enviadas ao servidor.





Essa abordagem tem duas desvantagens significativas:





  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









-

"Inscrição em um evento"
« »





"Publicando um evento"
« »
"Transmissão"
« »
"Cancelando inscrição em um evento"
« »





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