发送:
ChatInput.jsx
const file = event.target.files[0];
const { roomClient } = this.props;
const reader = new FileReader();
reader.onload = (e) => {
// 先发送文件信息
// 也可使用 bot 发送,@bot (.*)
if (this.start === 0)
roomClient.sendChatMessage(`hx1:{"name":"${file.name}","size":"${file.size}","type":"${file.type}"}`);
this.start += e.loaded;
// 发送分割的 ArrayBuffer
roomClient.sendDataMessage(reader.result);
console.log('发送文件', reader.result.byteLength);
if (this.start < this.total) {
const blob = file.slice(this.start, this.start + this.step);
setTimeout(() => {
reader.readAsArrayBuffer(blob);
}, 50);
} else {
console.log('发送文件完成');
}
}
// 初始化分割数据(Sctp消息有最大限制,详见server端config.js中的maxSctpMessageSize)
this.total = file.size;
this.start = 0;
this.step = 100000; // 这里使用100000配合Timeout 50 传输最为稳定
const blob = file.slice(this.start, this.start + this.step);
setTimeout(() => {
reader.readAsArrayBuffer(blob);
}, 50);
接收:
RoomClient.js
dataConsumer.on('message', (message) => {
if (message instanceof ArrayBuffer || message instanceof Blob) { // Failed to execute 'send' on 'RTCDataChannel': Blob support not implemented yet
const length = message.byteLength;
console.log('接收文件:', length);
this.recvsize += length;
if (!this.slice) this.slice = length;
this.blobs.push(new Blob([message]));
if (length < this.slice || length === this.filesize) {
console.log('接收文件完成', this.recvsize);
var file1 = new File(this.blobs, this.filename, {
type: this.filetype
});
window.open(URL.createObjectURL(file1));
}
return;
}
switch (dataConsumer.label) {
case 'chat': {
if (message.startsWith('hx1:')) {
const filejson = JSON.parse(message.substring(4));
console.log('接收文件:', filejson);
// 初始化接收数据
this.filename = filejson.name;
this.filesize = parseInt(filejson.size);
this.recvsize = 0;
this.slice = 0;
this.blobs = [];
this.filetype = filejson.type;
} else {
// show normal text message
}
// ....
});