浏览器窗口之间同步上传文件

对于 码头,我目前正在开发数字鼻子的应用程序。

这个应用程序需要上传BSEC配置文件--这是二进制数据。

一旦用户上传了文件,它就会通过MQTT发布,picockpit-client可以用它来配置BSEC AI算法来进行气体检测。

这里是部分网络界面的小预览。

形象

在Vuetify中,有一个内置的GUI元素:v-file-input。

<v-file-input
     v-model="bsecFile"
     label="来自AI Studio的BSEC配置文件(.config)"
     placeholder="在这里上传你的BSEC配置文件"
     prepend-icon="mdi-paperclip"
     概述
     浓密的
     显示尺寸
     accept=".config"
     @change="doUpload"
>
</v 文件输入

在这种情况下。 bsecFile 是我的模型。

注意:由于它是一个模型,它也可以被写到!

在MQTT上发布

这就是处理程序代码doUpload的样子(仍然包括调试信息)。

    doUpload(){
         console.log("model:")。
         console.log(this.bsecFile)。
         如果(this.bsecFile){
             // 下面的代码不能可靠地工作,尽管它在理论上应该如此
             // if (this.bsecFile.name.split(".")[1] != "config"){
             // console.log("文件名不包括.config - 重置。")。
             // this.bsecFile = null。
             // }
             // 否则 {
                 console.log("该变量似乎没有问题,正在尝试发布")。
                 var reader = new FileReader();
                 reader.addEventListener('load', (event) => {
                     console.log("文件读取成功!发布(现在用Uint8Array)。")。
                     // fn = 文件名, fs = 文件大小, fd = 文件(二进制)数据
                     const msg = {
                           fn:this.bsecFile.name。
                           fs: this.bsecFile.size。
                           fd: new Uint8Array (event.target.result)
                     }
                     console.log("消息是:")。
                     console.log(msg)。
                     this.$emit("bsec-upload-event", true)。
                     myMqtt.sendWBasePath(sensorSetBsecPath, msg, 1, true)。                   
                 });
                 reader.readAsArrayBuffer(this.bsecFile)。
         }
         否则 {
             console.log("该文件刚刚被清除,所以我们应该删除它......发送$nofile为true")。
             const msg = {
                 "$nofile": true
             }
             console.log("消息是:")。
             console.log(msg)。
             this.$emit("bsec-upload-event", false)。
             myMqtt.sendWBasePath(sensorSetBsecPath, msg, 1, true)。
         }
     }

请注意,我发布的信息包括二进制数据。

我为一个新的Uint8Array使用了一个构造函数,我把event.target.result--一个ArrayBuffer传给它。

这样一来,数据就会被准确地传递下去。

我们使用MsgPack将JavaScript对象打包成一个消息--它支持二进制数据。

在另一边,PiCockpit客户端接收二进制信息,并可以恢复一个(在这种情况下)Python对象,包括二进制数据。

让它在跨浏览器窗口的同步中发挥作用

第二个任务是在不同的浏览器窗口以及用户的会话中同步状态。

当用户返回时,我们希望将文件显示为已经上传给他们。

我想做的基本上是在JavaScript中建立一个新的文件对象实例,从我的Uint8Array中重新创建MQTT消息中的文件!

当然,我们订阅并监听MQTT消息。然后我们监测变量的变化,并修改模型bsecFile如下。

globalBsecFileWrapped(val){
     // 如果我们不负责发送该信息,这将只被更新。
     console.log("watch > globalBsecFileWrapped > contents:")。
     console.log(this.globalBsecFileWrapped)。
     console.log("我们现在要把它设置为一个文件......")。
     如果(this.globalBsecFileWrapped.hasOwnProperty("$nofile")){
         如果(this.globalBsecFileWrapped['$nofile']){
             //将其更新为空--它是由不同的浏览器重置的。
             this.bsecFile = null。
         }
     }
     else if (this.globalBsecFileWrapped.hasOwnProperty("fd") && this.globalBsecFileWrapped.hasOwnProperty("fn") ) {
         // 尝试 2
         // this.bsecFile = new File(this.globalBsecFileWrapped.fd, this.globalBsecFileWrapped.fn) 。
         this.bsecFile = new Blob([this.globalBsecFileWrapped.fd], {type: "application/octet-stream"});
         this.bsecFile.name = this.globalBsecFileWrapped.fn。
         // 调试
             var reader = new FileReader();
             reader.addEventListener('load', (event) => {
                 console.log("Debug >> File read successfully! publishing (now with Uint8Array).")。
                 // fn = 文件名, fs = 文件大小, fd = 文件(二进制)数据
                 const msg = {
                       fn:this.bsecFile.name。
                       fs: this.bsecFile.size。
                       fd: new Uint8Array (event.target.result)
                 }
                 console.log("消息是:")。
                 console.log(msg)。
             });
             reader.readAsArrayBuffer(this.bsecFile)。               
     }
}

注意这里的重要部分。

this.bsecFile = new Blob([this.globalBsecFileWrapped.fd], {type: "application/octet-stream"});
this.bsecFile.name = this.globalBsecFileWrapped.fn。

因此,为了重新创建文件(并让vuetify v-file-input更新为正确的文件(适当地显示大小和文件名),我们正在构建一个新的Blob。

重要提示:Blob的类型必须是 "application/octet-stream",否则将被解释为不同的类型,文件大小也将不再匹配。

最后,我们设置了新的名称--就这样了!"。

想解决类似的问题?

我们可供租用