应用 - 上传文件 + 元信息
上传文件,算是一种场景应用了。大文件(或大数据块)上传时,可进行配置优化:
- 服务端
- 使用临时文件分片处理方案(FragmentHandlerTempfile)
- 处理完成后,执行释放动作 message.release()
- 客户端
- 可以使用更小的分片大小(比如 1M)
1、客户端
//::打开客户端会话(使用更小的分片大小,可以节点内存)
const clientSession = await SocketD.createClient("sd:ws://127.0.0.1:8602/?u=a&p=2")
.config(c -> c.fragmentSize(1024 * 1024)) //1m
.open();
//发送 + 元信息
clientSession.send("/demo", SocketD.newEntity("{user:'noear'}").metaPut("trace-id", "1"));
//定义上传函数
function upload(){
const file1 = document.getElementById("file").files[0];
//发送文件
clientSession.sendAndRequest("/upload", SocketD.newEntity(file1)).thenReply(reply => {
console.log('reply', reply);
}).thenProgress((isSend, val, max)=>{
if(isSend){
//获取发送进度
}
});
}
2、服务端(以 java 为例)
使用临时文件方案(FragmentHandlerTempfile),更省内存
public class Demo {
public static void main(String[] args) throws Throwable {
//::启动服务端
SocketD.createServer("sd:ws")
.config(c -> c.port(8602).fragmentHandler(new FragmentHandlerTempfile()))
.listen(new EventListener().doOn("/upload", (s, m) -> {
String fileName = m.meta(EntityMetas.META_DATA_DISPOSITION_FILENAME);
if (fileName != null) {
File fileNew = new File("/data/upload/user.jpg");
fileNew.createNewFile();
//使用通道机制,性能更好
try (FileChannel fileChannel = new FileOutputStream(fileNew).getChannel()) {
fileChannel.write(m.data());
} finally {
//使用 FragmentHandlerTempfile 时,须对消息做资源释放(就是删除临时文件)
m.release();
}
} else {
System.out.println(m);
}
if (m.isRequest()) {
s.reply(m, new StringEntity("收到!"));
}
}).doOn("/hello",(s,m)->{
if (m.isRequest()) {
s.reply(m, new StringEntity("me too!"));
}
}))
.start();
}
}