Web Socket 上传文件并在同一端点发送 json

Web Socket upload file and send json on the same endpoint

我正在使用 Jetty 为聊天应用程序实施 JSR-356 Web 套接字。 对于托管对话和发送不同的消息类型,我使用的是使用 Jackson 和 TextDecoder

序列化 from/to json 的 DTO 对象
public class JsonDtoCodec implements Decoder.Text<Dto>,Encoder.Text<Dto>{
        ObjectMapper om = ... //some object mapper

        @Override
        public Dto decode(String json) throws DecodeException {
            Dto dto = null;
            try {
                dto = om.readValue(json,Dto.class);
            } catch (IOException e) {
                //ToDo add Log
            }
            return dto;
        }

        @Override
        public String encode(Dto dto) throws EncodeException {
            try {
                return om.writeValueAsString(dto);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

现在,在我的端点中,我使用直接 Dto 对象:

    @ServerEndpoint(value = "/{version}/{userType}/{token}",
            decoders =JsonDtoCodec.class,
            encoders = JsonDtoCodec.class)
    public class ChatServerEndPoint {

     @OnMessage
        public void onMessage(final @PathParam("userType") String userType,
                              final @PathParam("token") String token,
                              final @PathParam("version") String version,
                              final Session session,
                              Dto dto)
                throws IOException {

               //handling all DTO related object and sending response
               Dto response = .... // create some DTO
               session.getAsyncRemote().sendObject(dto);

    } 
}

不幸的是,我需要处理通过网络套接字上传最大 100Kb 大小的图像文件。

我可以使用同一个端点来处理 DTO 和二进制数据吗? 如果不是,我应该添加新的 EndPoint 并且我应该处理两个单独的连接,一个用于二进制文件,一个用于 Json 内容?

你当然可以。

您将有 2 个 @OnMessage 注释方法。 (一个处理文本,另一个处理二进制)

假设您的 JsonToDtoCodec 扩展了 Decoder.Text<Dto>,那么您的其他方法将被声明为 ...

@OnMessage(maxMessageSize=100000)
public void onFileUpload(final Session session, final ByteBuffer buf)
{
}

既然你说文件最大为100kb,那么将方法传入完整ByteBuffer就足够了。如果它更大,您可以改用 InputStream 方法。至于限制该缓冲区的大小,您的 maxMessageSize 注释将保持理智。

注意:如果客户端尝试发送超过 100kb 的二进制文件,则连接将关闭并使用关闭代码 1009: Too Big