Skip to content

Commit

Permalink
Use Blob messages to encode Blob and ArrayBuffer input
Browse files Browse the repository at this point in the history
  • Loading branch information
liamwhite committed Aug 10, 2024
1 parent 5e95d95 commit da50734
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 23 deletions.
48 changes: 31 additions & 17 deletions assets/js/phoenix/longpoll.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ import {
import Ajax from "./ajax"

let arrayBufferToBase64 = (buffer) => {
let binary = ""
let bytes = new Uint8Array(buffer)
let len = bytes.byteLength
for(let i = 0; i < len; i++){ binary += String.fromCharCode(bytes[i]) }
return btoa(binary)
return new Promise((resolve, reject) => {
let reader = new FileReader()
let blob = new Blob([buffer])
reader.onload = e => {
let dataStart = reader.result.indexOf(',')
resolve(reader.result.slice(dataStart + 1))
}
reader.onerror = () => reject()
reader.readAsDataURL(blob)
})
}

export default class LongPoll {
Expand All @@ -24,6 +29,7 @@ export default class LongPoll {
this.currentBatch = null
this.currentBatchTimer = null
this.batchBuffer = []
this.sendResolver = Promise.resolve()
this.onopen = function (){ } // noop
this.onerror = function (){ } // noop
this.onmessage = function (){ } // noop
Expand Down Expand Up @@ -118,18 +124,26 @@ export default class LongPoll {
// pushes against an empty buffer

send(body){
if(typeof(body) !== "string"){ body = arrayBufferToBase64(body) }
if(this.currentBatch){
this.currentBatch.push(body)
} else if(this.awaitingBatchAck){
this.batchBuffer.push(body)
} else {
this.currentBatch = [body]
this.currentBatchTimer = setTimeout(() => {
this.batchSend(this.currentBatch)
this.currentBatch = null
}, 0)
}
this.sendResolver =
this.sendResolver
.then(() => {
if(typeof(body) !== "string"){ return arrayBufferToBase64(body) }
return body
})
.then(body => {
if(this.currentBatch){
this.currentBatch.push(body)
} else if(this.awaitingBatchAck){
this.batchBuffer.push(body)
} else {
this.currentBatch = [body]
this.currentBatchTimer = setTimeout(() => {
this.batchSend(this.currentBatch)
this.currentBatch = null
this.sendResolver = Promise.resolve()
}, 0)
}
})
}

batchSend(messages){
Expand Down
8 changes: 2 additions & 6 deletions assets/js/phoenix/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default {
KINDS: {push: 0, reply: 1, broadcast: 2},

encode(msg, callback){
if(msg.payload.constructor === ArrayBuffer){
if(msg.payload.constructor === ArrayBuffer || msg.payload.constructor === Blob){
return callback(this.binaryEncode(msg))
} else {
let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]
Expand Down Expand Up @@ -45,11 +45,7 @@ export default {
Array.from(topic, char => view.setUint8(offset++, char.charCodeAt(0)))
Array.from(event, char => view.setUint8(offset++, char.charCodeAt(0)))

var combined = new Uint8Array(header.byteLength + payload.byteLength)
combined.set(new Uint8Array(header), 0)
combined.set(new Uint8Array(payload), header.byteLength)

return combined.buffer
return new Blob([header, payload])
},

binaryDecode(buffer){
Expand Down

0 comments on commit da50734

Please sign in to comment.