أنا متأكد من أن كل مطور ويب قد واجه مهمة التحديث الفوري لواجهة مستخدم ويب WEB حسب الحدث في النهاية الخلفية. والمثال الكلاسيكي هو الدردشة على شبكة الإنترنت (إذا كنت قد كتبت بالفعل بك النار الدردشة على شبكة الإنترنت، يمكنك تخطي مزيد من القراءة، وعلى الأرجح كنت تعرف كل شيء أدناه).
في X5 ، أواجه مثل هذه المهام بتردد يحسد عليه. يجب أن أقول إن جميع أنواع الدردشات وروبوتات المحادثة وغيرها من تفاعلات المستخدم النهائي في RealTime تتجه الآن. في هذا المقال ، أريد أن ألخص تجربتي في هذا الأمر وأشاركها مع قراء هبر.
صياغة المشكلة
نحن بحاجة إلى الجميع و كفاءة النقل لتقديم الأحداث من واجهة المستخدم WEB (متصفح المستخدم) إلى الخادم والعودة من الخادم إلى واجهة المستخدم WEB
الخيار رقم 1 - المسوحات الدورية
الطريقة الأسهل والأكثر فاعلية
المعنى واضح من الاسم ، من جانب Client2 بشكل دوري ، على سبيل المثال ، مرة واحدة كل ثانية ، يتم إرسال طلبات مثل "What are you doing؟" إلى الخادم.
هذا النهج له عيبان هامان:
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