gpt4 book ai didi

websocket - 发送文件认为Actix Websocket

转载 作者:行者123 更新时间:2023-12-03 11:36:09 27 4
gpt4 key购买 nike

我很难找到文档或教程,以便通过网络套接字发送文件。
这是我的JS:

['dragleave', 'drop'].forEach(event_name =>
document.addEventListener(event_name, function(e) {
e.preventDefault();
let files = e.dataTransfer.files;
var reader = new FileReader();
for(let i=0;i<files.length; i++) {
reader.onload = function(event) {
socket.send(event.target.result);
};
reader.readAsArrayBuffer(files[i]);
}
}, false));
我的rust代码基于官方示例( https://github.com/actix/examples/tree/master/websockets/websocket):
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for RatioUpWS {
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context,) {
// process websocket messages
println!("WS: {:?}", msg);
match msg {
Ok(ws::Message::Ping(msg)) => {
self.hb = Instant::now();
ctx.pong(&msg);
}
Ok(ws::Message::Pong(_)) => {self.hb = Instant::now();}
Ok(ws::Message::Text(text)) => {
ctx.text(text);
}
Ok(ws::Message::Binary(bin)) => {
let mut pos = 0;
let mut buffer = File::create("foo.txt").unwrap(); // notice the name of the file that will be written
while pos < bin.len() {
let bytes_written = buffer.write(&bin[pos..]).unwrap();
pos += bytes_written
};
ctx.binary(bin)
},
Ok(ws::Message::Close(reason)) => {
ctx.close(reason);
ctx.stop();
}
_ => ctx.stop(), //if file>64K, it goes here
}
}
}
它似乎被认为是文本消息,我不知道如何反序列化它。 actix_web::web::Form<FormDataStruct>似乎不合适。
任何的想法?

最佳答案

您的WebSocket服务器将消息识别为文本,因为您的JavaScript代码使用FormData()而不是ArrayBuffer调度文本数据。
要使用WebSocket从浏览器传输文件,可以使用以下示例代码(注意WebSocket声明和sendFile()函数):

    var ws;
function connectToWS() {
var wsUri = (window.location.protocol=='https:'&&'wss://'||'ws://')+window.location.host + '/ws/';
console.log(wsUri);
ws = new WebSocket(wsUri);
ws.binaryType = "arraybuffer"; // Note the binaryType here
ws.onopen = function() {alert("Connected.");};
ws.onmessage = function(evt) {alert(evt.msg);};
ws.onclose = function() {
ws = null;
alert("Connection is closed...");
};
ws.onerror = function(e) {alert(e.msg);}
}

function sendFile() {
var file = document.getElementById('filename').files[0];
var reader = new FileReader();
var rawData = new ArrayBuffer();
reader.loadend = function() {}
reader.onload = function(e) {
rawData = e.target.result;
ws.send(rawData);
alert("the File has been transferred.")
}
reader.readAsArrayBuffer(file);
}
要在服务器端处理传输的字节,可以使用标准的Rust库 (std::io::Write)。更改您提供的相同示例Rust代码以使用 std::io处理.txt文件:
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWebSocket {
fn handle(
&mut self,
msg: Result<ws::Message, ws::ProtocolError>,
ctx: &mut Self::Context,
) {
// process websocket messages
println!("WS: {:?}", msg);
match msg {
Ok(ws::Message::Ping(msg)) => {
self.hb = Instant::now();
ctx.pong(&msg);
}
Ok(ws::Message::Pong(_)) => {
self.hb = Instant::now();
}
Ok(ws::Message::Text(text)) => ctx.text(text),
Ok(ws::Message::Binary(bin)) => {
let mut pos = 0;
let mut buffer = File::create("foo.txt").unwrap(); // notice the name of the file that will be written
while pos < bin.len() {
let bytes_written = buffer.write(&bin[pos..]).unwrap();
pos += bytes_written
};
ctx.binary(bin)
},
Ok(ws::Message::Close(reason)) => {
ctx.close(reason);
ctx.stop();
}
_ => ctx.stop(),
}
}
}
您可以在此存储库中查看完整的工作示例: https://github.com/vnderlev/actix_ws_file_transfer(改编自 official actix/example repository)。
希望这个答案对您有所帮助。

关于websocket - 发送文件认为Actix Websocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66607517/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com