Keep track of client status in Client
This commit is contained in:
@@ -13,6 +13,14 @@ const permanentCaps = [
|
||||
];
|
||||
|
||||
export default class Client extends EventTarget {
|
||||
static Status = {
|
||||
DISCONNECTED: "disconnected",
|
||||
CONNECTING: "connecting",
|
||||
REGISTERING: "registering",
|
||||
REGISTERED: "registered",
|
||||
};
|
||||
|
||||
status = Client.Status.DISCONNECTED;
|
||||
ws = null;
|
||||
nick = null;
|
||||
params = {
|
||||
@@ -23,7 +31,6 @@ export default class Client extends EventTarget {
|
||||
pass: null,
|
||||
saslPlain: null,
|
||||
};
|
||||
registered = false;
|
||||
availableCaps = {};
|
||||
enabledCaps = {};
|
||||
batches = new Map();
|
||||
@@ -33,12 +40,19 @@ export default class Client extends EventTarget {
|
||||
|
||||
this.params = Object.assign(this.params, params);
|
||||
|
||||
this.reconnect();
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
this.disconnect();
|
||||
this.setStatus(Client.Status.CONNECTING);
|
||||
|
||||
try {
|
||||
this.ws = new WebSocket(params.url);
|
||||
this.ws = new WebSocket(this.params.url);
|
||||
} catch (err) {
|
||||
setTimeout(() => {
|
||||
this.dispatchEvent(new CustomEvent("error", { detail: "Failed to create connection: " + err }));
|
||||
this.dispatchEvent(new CustomEvent("close"));
|
||||
this.setStatus(Client.Status.DISCONNECTED);
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
@@ -47,7 +61,8 @@ export default class Client extends EventTarget {
|
||||
|
||||
this.ws.addEventListener("close", () => {
|
||||
console.log("Connection closed");
|
||||
this.dispatchEvent(new CustomEvent("close"));
|
||||
this.ws = null;
|
||||
this.setStatus(Client.Status.DISCONNECTED);
|
||||
});
|
||||
|
||||
this.ws.addEventListener("error", () => {
|
||||
@@ -55,8 +70,23 @@ export default class Client extends EventTarget {
|
||||
});
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.ws) {
|
||||
this.ws.close(1000);
|
||||
}
|
||||
}
|
||||
|
||||
setStatus(status) {
|
||||
if (this.status === status) {
|
||||
return;
|
||||
}
|
||||
this.status = status;
|
||||
this.dispatchEvent(new CustomEvent("status"));
|
||||
}
|
||||
|
||||
handleOpen() {
|
||||
console.log("Connection opened");
|
||||
this.setStatus(Client.Status.REGISTERING);
|
||||
|
||||
this.nick = this.params.nick;
|
||||
|
||||
@@ -88,12 +118,12 @@ export default class Client extends EventTarget {
|
||||
case irc.RPL_WELCOME:
|
||||
if (this.params.saslPlain && this.availableCaps["sasl"] === undefined) {
|
||||
console.error("Server doesn't support SASL PLAIN");
|
||||
this.close();
|
||||
this.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Registration complete");
|
||||
this.registered = true;
|
||||
this.setStatus(Client.Status.REGISTERED);
|
||||
break;
|
||||
case "CAP":
|
||||
this.handleCap(msg);
|
||||
@@ -109,7 +139,7 @@ export default class Client extends EventTarget {
|
||||
break;
|
||||
case irc.RPL_SASLSUCCESS:
|
||||
console.log("SASL authentication success");
|
||||
if (!this.registered) {
|
||||
if (this.status != Client.Status.REGISTERED) {
|
||||
this.send({ command: "CAP", params: ["END"] });
|
||||
}
|
||||
break;
|
||||
@@ -119,7 +149,7 @@ export default class Client extends EventTarget {
|
||||
case irc.ERR_SASLABORTED:
|
||||
case irc.ERR_SASLALREADY:
|
||||
this.dispatchEvent(new CustomEvent("error", { detail: "SASL error (" + msg.command + "): " + msg.params[1] }));
|
||||
this.close();
|
||||
this.disconnect();
|
||||
break;
|
||||
case "PING":
|
||||
this.send({ command: "PONG", params: [msg.params[0]] });
|
||||
@@ -148,7 +178,7 @@ export default class Client extends EventTarget {
|
||||
break;
|
||||
case "ERROR":
|
||||
this.dispatchEvent(new CustomEvent("error", { detail: "Fatal IRC error: " + msg.params[0] }));
|
||||
this.close();
|
||||
this.disconnect();
|
||||
break;
|
||||
case irc.ERR_PASSWDMISMATCH:
|
||||
case irc.ERR_ERRONEUSNICKNAME:
|
||||
@@ -158,8 +188,8 @@ export default class Client extends EventTarget {
|
||||
case irc.ERR_NOPERMFORHOST:
|
||||
case irc.ERR_YOUREBANNEDCREEP:
|
||||
this.dispatchEvent(new CustomEvent("error", { detail: "Error (" + msg.command + "): " + msg.params[msg.params.length - 1] }));
|
||||
if (!this.registered) {
|
||||
this.close();
|
||||
if (this.status != Client.Status.REGISTERED) {
|
||||
this.disconnect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -229,7 +259,7 @@ export default class Client extends EventTarget {
|
||||
|
||||
this.requestCaps(reqCaps);
|
||||
|
||||
if (!this.registered && capEnd) {
|
||||
if (this.status != Client.Status.REGISTERED && capEnd) {
|
||||
this.send({ command: "CAP", params: ["END"] });
|
||||
}
|
||||
}
|
||||
@@ -261,7 +291,7 @@ export default class Client extends EventTarget {
|
||||
break;
|
||||
case "NAK":
|
||||
console.log("Server nak'ed caps:", args[0]);
|
||||
if (!this.registered) {
|
||||
if (this.status != Client.Status.REGISTERED) {
|
||||
this.send({ command: "CAP", params: ["END"] });
|
||||
}
|
||||
break;
|
||||
@@ -287,11 +317,6 @@ export default class Client extends EventTarget {
|
||||
console.log("Sent:", msg);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.ws.close(1000);
|
||||
this.registered = false;
|
||||
}
|
||||
|
||||
/* Execute a command that expects a response. `done` is called with message
|
||||
* events until it returns a truthy value. */
|
||||
roundtrip(msg, done) {
|
||||
|
||||
Reference in New Issue
Block a user