Socket.D v2.5.11

应用 - 上传文件 + 元信息

</> markdown

上传文件,算是一种场景应用了。大文件(或大数据块)上传时,可进行配置优化:

  • 服务端
    • 使用临时文件分片处理方案(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();
    }
}