Saya yakin setiap pengembang web telah menghadapi tugas untuk memperbarui UI WEB secara cepat dengan acara di back-end. Contoh klasik adalah obrolan web (jika Anda telah menulis obrolan web api , Anda dapat melewati membaca lebih lanjut, kemungkinan besar Anda sudah mengetahui semuanya di bawah).
Di X5, saya menghadapi tugas-tugas seperti itu dengan frekuensi yang membuat iri. Saya harus mengatakan semua jenis obrolan, chatbots, dan interaksi pengguna akhir RealTime lainnya sedang tren sekarang. Pada artikel kali ini, saya ingin merangkum pengalaman saya dalam hal ini dan membaginya dengan para pembaca Habr.
Rumusan masalah
Kami membutuhkan transportasi universal dan efisien untuk mengirimkan acara dari WEB UI (browser pengguna) ke server dan kembali dari server ke WEB UI
Opsi # 1 - SURVEI BERKALA
cara termudah dan paling tidak efektif
Artinya jelas dari namanya, dari sisi Client2 secara berkala, misalnya setiap 1 detik sekali, request seperti βWhat are you doing?β Dikirim ke server.
Pendekatan ini memiliki dua kelemahan signifikan:
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