在标题帧和数据帧之间意外切换

时间:2017-12-28 07:25:05

标签: netty

我们现在正在开发一个使用Netty的客户端 - 服务器系统。 我们有时会发现通信错误。 如果我们错误地使用Netty,你能给我一些建议。

我们在以下sendResponse中按此顺序调用writeHeadersFrame和writeDataFrame。

但我们有时会发现Headers框架和数据框之间的意外切换。

  private def sendResponse(
                            streamId: Int,
                            name: String,
                            status: ResponseStatus,
                            options: Map[String, String],
                            data: Option[PackableData],
                            isLast: Boolean): Unit =
    requestTable.get(streamId) match {
      case None =>
        log.error(s"sendResponse: streamId not found: $streamId")
      case Some(requestInfo) if requestInfo.ctx.channel.isActive =>
        writeResponseAccessLog(requestInfo.connectionTime, requestInfo.path, requestInfo.remoteAddress, status)
        writeHeadersFrame(requestInfo, streamId, status, isHeadersFrameEndStream(data, isLast))
        writeDataFrame(requestInfo, streamId, data, isLast)
        flush(requestInfo)
        removeStreamIdIfLast(streamId, isLast)
      case _ => detectedDisconnectionAndStop
    }


  private def writeHeadersFrame(requestInfo: RequestInfo, streamId: Int, status: ResponseStatus, isLast: Boolean): Unit = {
    log.debug(s"writeHeadersFrame($streamId, $status, $isLast)")
    val headers = new DefaultHttp2Headers().status(status.code.toString)
    headers.set(new AsciiString("content-type"), new AsciiString("application/x-msgpack"))

    val promise = requestInfo.ctx.newPromise()
    promise.addListener(new NettyChannelFutureListener(self))
    encoder.writeHeaders(requestInfo.ctx, streamId, headers, 0, isLast, promise)
  }




 private def writeBytesArray(ctx: ChannelHandlerContext, streamId: Int, bytes: Array[Byte], isLast: Boolean): Unit = {
    val byteBuffer = Unpooled.copiedBuffer(bytes)
    val promise: ChannelPromise = ctx.newPromise()
    promise.addListener(new NettyChannelFutureListener(self))
    log.debug(s"writeDataFrame: DATA Frame ${bytes.length} bytes, Readable bytes=${byteBuffer.readableBytes()}")
    encoder.writeData(ctx, streamId, byteBuffer, 0, isLast, promise)
  }

  private def writeDataFrame(requestInfo: RequestInfo, streamId: Int, data: Option[PackableData], isLast: Boolean): Unit = {
    log.debug(s"writeDataFrame: $streamId, $data, $isLast)")

    data match {
      case None =>
        log.info("writeDataFrame: No Data")
      case Some(packable) =>
        MessagePackUtil.serialize(packable) match {
          case Failure(e) =>
            log.error(s"writeDataFrame: serialize error: ${e.getMessage}")
          case Success(bytes: Array[Byte]) =>
            writeBytesArray(requestInfo.ctx, streamId, bytes, isLast)
        }
    }
  }

0 个答案:

没有答案