Skip to content

Commit

Permalink
Fix issue Bitcoin-com#173 relating to redundant / zombie Socket conne…
Browse files Browse the repository at this point in the history
…ctions.
  • Loading branch information
rnbrady committed Feb 13, 2020
1 parent a25b22a commit fb9ff35
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 33 deletions.
82 changes: 49 additions & 33 deletions lib/Socket.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,70 @@
import { BITSOCKET_URL, WS_URL } from "./BITBOX"
import { SocketConfig } from "./interfaces/BITBOXInterfaces"
import io from "socket.io-client"
import EventSource from "eventsource"

enum SocketType {
Uninitialized,
SocketIO,
BitSocket
}

const io: any = require("socket.io-client")
export class Socket {
socket: any
websocketURL: string
bitsocketURL: string
constructor(config: SocketConfig = {}) {
if (config.wsURL) {
// default to passed in wsURL
this.websocketURL = config.wsURL
} else if (config.restURL) {
// 2nd option deprecated restURL
this.websocketURL = config.restURL
} else {
// fallback to WS_URL
this.websocketURL = WS_URL
}

if (config.bitsocketURL) {
this.bitsocketURL = config.bitsocketURL
} else {
this.bitsocketURL = BITSOCKET_URL
}
socketType: SocketType = SocketType.Uninitialized

constructor(config: SocketConfig = {}) {
// Order of preference: passed in wsURL, deprecated restURL, fallback WS_URL
this.websocketURL = config.wsURL || config.restURL || WS_URL
// Similar for BitSocket case
this.bitsocketURL = config.bitsocketURL || BITSOCKET_URL
// Execute callback (immediate, synchronous and unconditional)
if (config.callback) config.callback()
// Note that we can't set socketType in constructor as config may contain
// both socket.io and BitSocket URLs, so we need to wait for listen() before
// we know which type it will be.
}

public listen(query: string, cb: Function): void {
if (query === "blocks" || query === "transactions") {
this.socket = io(this.websocketURL, { transports: ["websocket"] })
this.socket.emit(query)

if (query === "blocks") this.socket.on("blocks", (msg: any) => cb(msg))
else if (query === "transactions")
this.socket.on("transactions", (msg: any) => cb(msg))
} else {
let EventSource = require("eventsource")
let b64 = Buffer.from(JSON.stringify(query)).toString("base64")
this.socket = new EventSource(`${this.bitsocketURL}/s/${b64}`)
this.socket.onmessage = (msg: any) => {
cb(msg.data)
// socket.io case
switch (this.socketType) {
case SocketType.Uninitialized:
this.socketType = SocketType.SocketIO
this.socket = io(this.websocketURL, { transports: ["websocket"] })
case SocketType.SocketIO:
// Send server the event name of interest. At time of writing this is
// not used by the server but is left in so that server-side filtering
// is an option in the future.
this.socket.emit(query)
this.socket.on(query, (msg: any) => cb(msg))
break;
case SocketType.BitSocket:
throw new Error("Query type not possible on a BitSocket connection.")
}
} else {
// BitSocket case
switch (this.socketType) {
case SocketType.Uninitialized:
this.socketType = SocketType.BitSocket
let b64 = Buffer.from(JSON.stringify(query)).toString("base64")
this.socket = new EventSource(`${this.bitsocketURL}/s/${b64}`)
this.socket.onmessage = (msg: any) => {
cb(msg.data)
}
break;
case SocketType.BitSocket:
throw new Error("Only one BitSocket query can be run at a time.")
case SocketType.SocketIO:
throw new Error("Query type not possible on a SocketIO connection.")
}
}
}

public close(cb?: Function): void {
this.socket.close()
if (cb) {
cb()
}
if (cb) cb()
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@bitcoin-dot-com/bitcoincashjs2-lib": "^4.1.0",
"@types/bigi": "^1.4.2",
"@types/bip39": "^2.4.2",
"@types/eventsource": "^1.1.2",
"@types/randombytes": "^2.0.0",
"@types/socket.io": "^2.1.2",
"@types/socket.io-client": "^1.4.32",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,11 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==

"@types/eventsource@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@types/eventsource/-/eventsource-1.1.2.tgz#079ab4213e844e56f7384aec620e1163dab692b3"
integrity sha512-4AKWJ6tvEU4fk0770oAK4Z0lQUuSnc5ljHTcYZhQtdP7XMDKKvegGUC6xGD8+4+F+svZKAzlxbKnuGWfgMtgVA==

"@types/glob@^7.1.1":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
Expand Down

0 comments on commit fb9ff35

Please sign in to comment.