java.lang.Object
de.craftsblock.craftsnet.api.websocket.Frame
All Implemented Interfaces:
RequireAble

public class Frame extends Object implements RequireAble
Represents a WebSocket frame that contains control information and payload data. This class handles parsing of WebSocket frames, managing frame attributes, and processing the frame data according to the WebSocket protocol.

A WebSocket frame consists of (as described in RFC 6455):

  • A FIN bit indicating if this is the final frame in a sequence of fragmented frames.
  • RSV1, RSV2, and RSV3 bits for protocol-specific extensions which are typically set to zero.
  • An opcode that defines the type of the frame (e.g., text, binary, close, ping, pong).
  • Payload length indicating the size of the payload data.
  • Masking key used to mask the payload data for security purposes.
  • Payload data containing the actual message or control information.

This class supports reading frames from an input stream, handling fragmented frames, and decoding the payload data. It also provides methods to access frame attributes and manipulate the payload data.

Since:
3.0.6-SNAPSHOT
  • Constructor Summary

    Constructors
    Constructor
    Description
    Frame(boolean fin, boolean rsv1, boolean rsv2, boolean rsv3, boolean masked, @NotNull Opcode opcode, byte @NotNull [] data)
    Constructs a new Frame with the specified parameters.
    Frame(byte @NotNull [] frame, byte @NotNull [] data)
    Constructs a new Frame by decoding the provided frame header and payload data.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    Appends the data from the specified frame to the current frame.
    protected Object
    Creates a deep copy of this frame.
    protected Collection<Frame>
    fragmentFrame(int fragmentLength)
    Fragments the current frame into multiple smaller frames, each with a maximum length specified by the fragmentLength parameter.
    Gets the payload data of this frame a ByteBuffer.
    byte @NotNull []
    Gets the raw payload data of this frame.
    Gets the opcode of this frame which indicates the type of the frame.
    Gets the payload data of this frame as a UTF-8 encoded string.
    boolean
    Checks if this frame is the final frame in a sequence of fragmented frames.
    boolean
    Returns if the frame was masked (when received), or schuld be masked (when send)!
    boolean
    Checks if the RSV1 bit is set in the frame header.
    boolean
    Checks if the RSV2 bit is set in the frame header.
    boolean
    Checks if the RSV3 bit is set in the frame header.
    protected static Frame
    read(InputStream stream)
    Reads a WebSocket frame from the given input stream.
    void
    setData(byte[] data)
    Sets the payload data for this frame.
    void
    setMasked(boolean masked)
    Sets whether the frame should be masked when sent to the client.
    void
    setOpcode(@NotNull Opcode opcode)
    Sets the Opcode for the frame.
    protected void
    Writes the current frame to the specified output stream.

    Methods inherited from class java.lang.Object

    equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • Frame

      public Frame(boolean fin, boolean rsv1, boolean rsv2, boolean rsv3, boolean masked, @NotNull @NotNull Opcode opcode, byte @NotNull [] data)
      Constructs a new Frame with the specified parameters. This constructor initializes the frame with the provided values for the final frame indicator, reserved bits, opcode, and payload data.
      Parameters:
      fin - whether this frame is the final fragment in a message. If true, this is the final frame.
      rsv1 - the first reserved bit. Should be false unless an extension uses it.
      rsv2 - the second reserved bit. Should be false unless an extension uses it.
      rsv3 - the third reserved bit. Should be false unless an extension uses it.
      masked - whether the frame was masked, when it was received.
      opcode - the opcode of the frame, indicating the type of frame.
      data - the payload data of the frame. This array should not be null and contains the actual message data.
    • Frame

      public Frame(byte @NotNull [] frame, byte @NotNull [] data)
      Constructs a new Frame by decoding the provided frame header and payload data. This constructor extracts the final frame indicator, reserved bits, and opcode from the frame header, and sets the payload data.
      Parameters:
      frame - an array of bytes representing the frame header. The first byte should contain the FIN flag, reserved bits, and opcode.
      data - the payload data of the frame. This array should not be null and contains the actual message data.
      Throws:
      IllegalArgumentException - if the opcode derived from the frame header is invalid.
  • Method Details

    • isFinalFrame

      public boolean isFinalFrame()
      Checks if this frame is the final frame in a sequence of fragmented frames.
      Returns:
      true if this is the final frame, false otherwise.
    • isRsv1

      public boolean isRsv1()
      Checks if the RSV1 bit is set in the frame header.
      Returns:
      true if the RSV1 bit is set, false otherwise.
    • isRsv2

      public boolean isRsv2()
      Checks if the RSV2 bit is set in the frame header.
      Returns:
      true if the RSV2 bit is set, false otherwise.
    • isRsv3

      public boolean isRsv3()
      Checks if the RSV3 bit is set in the frame header.
      Returns:
      true if the RSV3 bit is set, false otherwise.
    • isMasked

      public boolean isMasked()
      Returns if the frame was masked (when received), or schuld be masked (when send)!
      Returns:
      true if the frame was masked, false otherwise.
    • setMasked

      public void setMasked(boolean masked)
      Sets whether the frame should be masked when sent to the client.
      Parameters:
      masked - Set to true if masking should be enabled, otherwise to false
    • getOpcode

      public Opcode getOpcode()
      Gets the opcode of this frame which indicates the type of the frame.
      Returns:
      The opcode of this frame.
    • setOpcode

      public void setOpcode(@NotNull @NotNull Opcode opcode)
      Sets the Opcode for the frame.
      Parameters:
      opcode - The new Opcode.
    • getBuffer

      public ByteBuffer getBuffer()
      Gets the payload data of this frame a ByteBuffer.
      Returns:
      The payload data as a ByteBuffer
    • getData

      public byte @NotNull [] getData()
      Gets the raw payload data of this frame.
      Returns:
      The raw payload data.
    • getUtf8

      public String getUtf8()
      Gets the payload data of this frame as a UTF-8 encoded string.
      Returns:
      The payload data as a UTF-8 string.
    • setData

      public void setData(byte[] data)
      Sets the payload data for this frame.
      Parameters:
      data - The payload data to set.
    • appendFrame

      protected void appendFrame(Frame frame)
      Appends the data from the specified frame to the current frame. This method is intended to be used for frames with the continuation opcode, allowing fragmented frames to be reassembled into a single frame. The method ensures that only continuation frames are appended and that appending is not attempted on a frame marked as final.

      This method is synchronized to ensure thread safety during the append operation. It updates the current frame's data by merging it with the data from the specified frame and appropriately sets the final (FIN) flag if either the current frame or the appended frame has the FIN flag set.

      Parameters:
      frame - the frame whose data is to be appended to the current frame. The frame must have the continuation opcode and the current frame must not be marked as final.
      Throws:
      IllegalStateException - if the frame's opcode is not continuation or if the current frame is already marked as final.
    • fragmentFrame

      protected Collection<Frame> fragmentFrame(int fragmentLength)
      Fragments the current frame into multiple smaller frames, each with a maximum length specified by the fragmentLength parameter. This is useful for splitting large frames into smaller fragments to comply with WebSocket protocol requirements for frame sizes.

      The resulting fragments are stored in a synchronized collection to ensure thread safety. Each fragment will have the same RSV1, RSV2, and RSV3 values as the original frame and a continuation opcode, except for the last fragment which will have its FIN bit set to true to indicate the final fragment.

      Parameters:
      fragmentLength - the maximum length of each fragmented frame. If the data length is less than or equal to fragmentLength, a single frame is returned.
      Returns:
      a collection of frames, each containing a portion of the original frame's data. The collection is guaranteed to be thread-safe.
    • write

      protected void write(OutputStream stream) throws IOException
      Writes the current frame to the specified output stream. This method encodes the frame header and payload data according to the WebSocket protocol. The method ensures that the frame is correctly formatted with the final frame indicator and the appropriate opcode, followed by the payload length and the actual payload data.
      Parameters:
      stream - the output stream to which the frame will be written.
      Throws:
      IOException - if an I/O error occurs while writing to the stream.
    • read

      protected static Frame read(InputStream stream) throws IOException
      Reads a WebSocket frame from the given input stream. This method reads the frame header and payload data from the provided input stream, handles the payload length based on the WebSocket protocol specifications, and decodes the payload data using the provided masking key.
      Parameters:
      stream - The input stream to read the frame from.
      Returns:
      The constructed Frame object containing the frame header and payload data.
      Throws:
      IOException - If an I/O error occurs while reading from the stream.
    • clone

      protected Object clone()
      Creates a deep copy of this frame.
      Overrides:
      clone in class Object
      Returns:
      The deep copy.