ln.vue/js/lib/ln.vue.websocket.js

138 lines
4.1 KiB
JavaScript

(function(){
class LNVueWebSocket
{
constructor(lnvue,o){
this.LNVue = lnvue;
this.options = Object.assign({},o);
if (!this.options.url)
this.options.url = this.constructURL();
this._id = 1;
this.defaultTimeout = 30000;
this.websocket = null;
this.callbacks = {};
this._state = "initialized";
this._retry = null;
this.closing = false;
}
constructURL(){
var pageURI = window.location;
var scheme = pageURI.scheme == "https" ? "wss:" : "ws:";
var host = pageURI.host;
return scheme + "//" + host + "/socket";
}
open(){
if (this._retry){
clearTimeout(this._retry);
}
this.closing = false;
this.websocket = new WebSocket(this.options.url);
this.websocket.onopen = (e) =>{
console.log("WebSocket connected");
this._state = "ONLINE";
let WSHello = {
ApplicationSessionID: this.LNVue.sessionID(),
};
console.log("WSHello request",WSHello);
this.request("WSHello",WSHello)
.then((wsh)=>{
console.log("WSHello response",wsh);
this.LNVue.sessionID(wsh.message.ApplicationSessionID);
this.LNVue.identity = new LN.Identity(wsh.message.SessionIdentity);
});
};
this.websocket.onclose = (e)=>{ this._onclose(e); this._state = "OFFLINE"; };
this.websocket.onerror = (e)=>{ this._onerror(e); this._state = "ERROR"; };
this.websocket.onmessage = (e)=>{ this._onmessage(e); };
return this;
}
close(){
if (this.websocket){
this.closing = true;
this.websocket.close(200,"close() called");
}
}
request(msgtype,msg,timeout){
let message = {
id: this._id++,
type: msgtype,
message: msg,
}
if (!timeout)
timeout = this.defaultTimeout;
if (timeout != -1){
return new Promise((resolve,reject)=>{
let to = setTimeout(()=>{
delete this.callbacks[message.id];
reject("timed out");
},timeout);
this.callbacks[message.id] = (msgtype,msg)=>{
clearTimeout(to);
delete this.callbacks[message.id];
if (msgtype == "error")
reject(msg);
else
resolve({type: msgtype,message: msg});
};
this.websocket.send(
JSON.stringify(message)
);
});
} else {
new Promise((resolve,reject)=>{
this.websocket.send(
JSON.stringify(message)
);
resolve();
});
}
}
_onclose(evt){
this.websocket = null;
this.options.onclose && this.options.onclose(evt);
if (!this.closing)
{
this._retry = setTimeout(() => {
this._retry = null;
console.log("reconnect...")
this.open();
}, 5000);
}
}
_onerror(evt){
this.options.onerror && this.options.onerror(evt);
}
_onmessage(evt){
try
{
let j = JSON.parse(evt.data);
let cb = this.callbacks[ j.id ];
cb && cb(j.type,j.message);
} catch(exc){
console.log(exc,evt.data);
}
}
}
LN.$add("LN.Vue.WebSocket",LNVueWebSocket);
})();