A convenience wrapper around de.lucaswerkmeister.ceylond.core for packet-based daemons. Packets are a useful abstraction on top of the core module, since the socket itself does not necessarily preserve boundaries between writes or reads: especially on internet-based sockets, transmissions may be fragmented and/or grouped together. This module takes care of that: a packet consists of a length, a type, and the content (length bytes), and is always delivered to the packet handler (registered as a TypeMap) as a single unit. The number of bytes in the length and type is specified by the user of this module; the type may be size zero to disable it completely.

See startPacketBased() for a usage example and makePacketBasedInstance() and its parameters for details.

Platform: JavaScript, Java
Packages
de.lucaswerkmeister.ceylond.packetBased

The main package.

Dependencies
de.lucaswerkmeister.ceylond.core1.0.0

The main package.

Aliases
TypeMapshared TypeMap=> Correspondence<Integer,ReadCallback>

A correspondence from packet type (an unsigned Integer) to read callback for packets of this type. Despite the name, this need not be a Map.

A type map may, for exammple, be constructed with Array or map.

Functions
makePacketBasedInstanceshared [ReadCallback, SocketExceptionHandler]? makePacketBasedInstance([TypeMap, SocketExceptionHandler]? instance(void write(ByteBuffer content, Integer type, WriteCallback callback), void close()), Integer lengthSize = ..., Integer typeSize = ..., Integer maximumLength = ...)(void write(ByteBuffer content, WriteCallback callback), void close())

Create an instance for start that reads and writes packets.

A packet consists of lengthSize bytes of length (in network byte order), typeSize bytes of type (in network byte order), and then length bytes of packet content..

Parameters:
  • instance

    This function is called whenever a new connection to the socket is opened. It works just like instance, except that write() also takes a packet type and the read callback is not a single function, but a TypeMap. If a packet with an unknown type (not defined by the type map) is returned, an error is logged and the connection is immediately closed. (The exception handler returned by instance() is not consulted in this case.)

  • lengthSize = 4

    The size of the packet length in bytes.

    • Length must be at least one byte long

  • typeSize = 4

    The size of the packet type in bytes. Set to 0 to disable packet types completely.

    • Type cannot be negative bytes long

  • maximumLength = 256^lengthSize - 1

    The maximum length for received packets. You may want to set this to a lower value than what can be stored within lengthSize bytes to avoid allocating huge amounts of memory on malformed or malicious input. If this packet exceeding this length is received, an error is logged and the connection is immediately closed. (The exception handler returned by instance() is not consulted in this case.)

readIntegershared Integer readInteger(ByteBuffer buffer)

Reads an unsigned Integer in network byte order (big-endian) from the given buffer, which must not have more than integerAddressableSize/8 bytes available. All available bytes in the buffer are read.

Parameters:
  • buffer
    • Does not support integers longer than the runtime addressable integer size

startPacketBasedshared void startPacketBased([TypeMap, SocketExceptionHandler]? instance(void write(ByteBuffer content, Integer type, WriteCallback callback), void close()), Integer fd, ServerExceptionHandler handler = ..., Boolean concurrent = true, Integer lengthSize = ..., Integer typeSize = ..., Integer maximumLength = ...)

Start listening on the socket, reading and writing packets.

Usage example:

startPacketBased {
    function instance(void write(ByteBuffer content, Integer type, WriteCallback callback), void close()) {
        void readAuth(ByteBuffer content) { ... }
        void readRemoteInvocation(ByteBuffer content) { ... }
        void readRemoteAccess(ByteBuffer content) { ... }

        value typeMap = map {
            0->readAuth,
            #101->readRemoteInvocation,
            #102->readRemoteAccess
        };
        return [typeMap, logAndAbort(`module`)];
    }
    lengthSize = 2;
    typeSize = 2;
    fd = switch (runtime.name) case ("jvm") 0 case ("node.js") 3 else -1;
};
Parameters:
  • instance
  • fd

    See fd.

  • handler = logAndAbort()

    See handler.

  • concurrent = true

    See concurrent.

  • lengthSize = 4
  • typeSize = 4

    See typeSize.

  • maximumLength = 256^lengthSize - 1

    See [[makePacketBasedInstance.maximumLength.

writeIntegershared void writeInteger(Integer integer, Integer size, ByteBuffer buffer)

Writes the given unsigned integer in network byte order (big-endian) to the buffer. Exactly size bytes of output are written.

Parameters:
  • integer
    • Does not support signed integers

    • Integer must fit into size bytes

  • size
    • Does not support integers longer than the runtime addressable integer size

    • Integer must fit into size bytes

    • Buffer must have size bytes available

  • buffer
    • Buffer must have size bytes available

Exceptions
MaximumLengthExceededExceptionshared MaximumLengthExceededException

The length specified in the packet header exceeds the maximum length defined by the application.

PacketProtocolExceptionshared abstract PacketProtocolException

An error in the packet protocol itself. Exceptions of this kind are fatal and result in immediate connection termination. They are not sent to the application���s exception handler.

UnknownTypeExceptionshared UnknownTypeException

The type specified in the packet header is unknown to the application.