フロントへのリアルタイムメッセージ配信

すべてのWeb開発者は、バックエンドのイベントごとにWEBUIを迅速に更新するという課題に直面していると確信しています。典型的な例はWebチャットです(Fire Webチャットを既に作成している場合は、さらに読むことをスキップできます。おそらく、以下のすべてをすでに知っているでしょう)。





X5では、うらやましい頻度でそのようなタスクに遭遇します。あらゆる種類のチャット、チャットボット、その他のリアルタイムのエンドユーザーとのやり取りが現在トレンドになっていると言わざるを得ません。この記事では、この問題に関する私の経験を要約し、Habrの読者と共有したいと思います。





問題の定式化

イベントをWEBUI(ユーザーのブラウザー)からサーバーに配信し、サーバーからWEB UIに戻すには、ユニバーサル効率的なトランスポートが必要です。





オプション#1-定期的な調査

最も簡単で最も効果のない方法









名前から明らかな意味は、Client2側から定期的に、たとえば1秒に1回、「何をしているの?」などのリクエストがサーバーに送信されます。





このアプローチには2つの重大な欠点があります。





  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









-

「イベントへの登録」
« »





「イベントの公開」
« »
"放送"
« »
「イベントの退会」
« »





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