-
-
Save joshualyon/ebd2f0886f38d71faf3dbc5bb0c000f3 to your computer and use it in GitHub Desktop.
Bitstamp Custom Tile (Realtime Socket)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://unpkg.com/vue@next"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script> | |
<div id="app"> | |
<div class="title">{{channel}}</div> | |
<span class="price">{{formattedPrice}}</span> | |
<div class="connection-status">{{connectionStatus}}</div> | |
</div> | |
<style> | |
html, body { height: 100%; margin: 0; } | |
#app { height: 100%; width: 100%;} | |
.title { position: fixed; top: 0.5em; left: 0; right: 0; text-align: center; font-size: 0.8em;} | |
.price { height: 100%; display: flex; align-items: center; justify-content: center; font-size: min(20vh, 20vw) } | |
.connection-status { position: fixed; bottom: 0.5em; left: 0.5em;font-size:0.8em;opacity:0.5;} | |
</style> | |
<script> | |
const Ticker = { | |
data() { | |
return { | |
ws: null, | |
timeout: 250, //250ms default, exponentially backs off | |
channel: "btcusd", | |
price: null, | |
isConnected: false | |
} | |
}, | |
computed: { | |
connectionStatus(){ | |
return this.isConnected ? 'Connected' : 'Connecting...'; | |
}, | |
formattedPrice(){ | |
if(this.price) return this.price.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) | |
} | |
}, | |
methods: { | |
initialize(){ | |
//simultaneously connect to the websocket and send an initial REST request for latest price | |
this.connect() | |
this.query(); | |
}, | |
query(){ | |
let url = `https://www.bitstamp.net/api/v2/ticker/${this.channel}/` | |
let proxiedUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(url)}` | |
axios.get(proxiedUrl).then((response) =>{ | |
if(response.data && response.data.contents){ | |
let data = JSON.parse(response.data.contents); | |
if(this.price == null && data.last != null) | |
this.price = Number(data.last); | |
} | |
}) | |
}, | |
connect() { | |
let ws = new WebSocket('wss://ws.bitstamp.net/'); | |
this.ws = ws; // copy it over for easier reference elsewhere | |
ws.onopen = this.onOpen; | |
ws.onmessage = this.onMessage; | |
ws.onclose = this.onClose; | |
ws.onerror = this.onError; | |
}, | |
onOpen(){ | |
this.isConnected = true; | |
let subscribeRequest = { | |
"event": "bts:subscribe", | |
"data": { | |
"channel": `live_trades_${this.channel}` | |
} | |
} | |
//subscribe to our desired data | |
this.ws.send(JSON.stringify(subscribeRequest)) | |
}, | |
onMessage(e){ | |
//handle the messages | |
console.log(e); | |
if(e.type === "message" && e.data){ | |
let message = JSON.parse(e.data); | |
if(message.event === "trade" && message.data != null && message.data.price != null){ | |
this.price = message.data.price | |
} | |
} | |
}, | |
onClose(e){ | |
this.isConnected = false; | |
//update next timeout retry, capped at 10 seconds | |
let timeout = Math.min(10000,this.timeout+=this.timeout) | |
let timeoutSeconds = timeout / 1000; | |
console.log(`[Socket Closed] Attemping reconnect in ${timeoutSeconds} seconds...`, e.reason); | |
setTimeout(this.connect, timeout); | |
}, | |
onError(err){ | |
console.error('[Socket Error] Closing socket, encountered error: ', err.message); | |
this.ws.close(); | |
} | |
}, | |
mounted(){ | |
this.initialize(); | |
} | |
} | |
let tickerInstance = Vue.createApp(Ticker).mount('#app') | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment