<commit_before># framing-socket

[![Build Status](https://travis-ci.org/matanamir/framing-socket.png)](https://travis-ci.org/matanamir/framing-socket)

FramingSocket adds variable size framing and simple promise-based notifications to normal sockets.

Note that the FramingSocket assumes a request/response protocol of some form where the first frame bytes are the
size of the frame, and each frame response contains an RPC ID to associate it with the sent request.  It uses the
[FramingBuffer][1] internally to handle this framing.

The user can define their own frame_length reader function and rpc_id reader function to find and parse those
values from the frame.

It also includes a simplistic backpressure mechanism based on the number of "falsey" write()s and will emit the
common pause/resume events based on this upstream.

**Note**: *Still experimental. Use with caution*

## Example

```js
var FramingSocket = require('framing-socket');

var options = {
    frame_length_size: 4,                           // frame_length field size in bytes
    frame_length_reader: function(offset_buffer) {  // custom function to read the frame_length
      return offset_buffer.readInt32BE();           // note that it passes in an OffsetBuffer (see 'offset-buffer' repo)
    }
    rpc_id_reader: function(offset_buffer) {        // custom function to read the rpc_id from the buffer
      return offset_buffer.readInt32BE();           // The frame_length field is stripped from this OffsetBuffer already
    }
};

var socket = new FramingSocket(options);
var rpc_id = 123;                                   // Unique RPC ID to identify this request (unique to this connection)

socket.connect('localhost', 8888).then(function on_connect() {
    return socket.write(rpc_id, new Buffer([0x01, 0x02, 0x03]));
}).then(function on_success(frame) {
    // do something with the returned frame (minus the frame_length bytes)
    // ....
    return socket.close();
}).then(function on_closed() {
    // socket closed
});
```

## Usage

### connect(host,port)
Creates a new socket and returns a promise

```js
framing_socket.connect(host, port).then(function on_connect() {
    // socket is now connected successfully...
}).otherwise(function on_error() {
    // failed to connect
});;
```

### close()
Closes an existing socket and returns a promise.

```js
framing_socket.close().always(function on_close() {
    // socket closed!
});
```

### write(rpc_id, data)
Write data to the socket and returns a promise for the response data.
The RPC ID is used to match the request and response together.

```js<commit_msg>adding documentation for the timeout option<commit_after># framing-socket

[![Build Status](https://travis-ci.org/matanamir/framing-socket.png)](https://travis-ci.org/matanamir/framing-socket)

FramingSocket adds variable size framing and simple promise-based notifications to normal sockets.

Note that the FramingSocket assumes a request/response protocol of some form where the first frame bytes are the
size of the frame, and each frame response contains an RPC ID to associate it with the sent request.  It uses the
[FramingBuffer][1] internally to handle this framing.

The user can define their own frame_length reader function and rpc_id reader function to find and parse those
values from the frame.

It also includes a simplistic backpressure mechanism based on the number of "falsey" write()s and will emit the
common pause/resume events based on this upstream.

**Note**: *Still experimental. Use with caution*

## Example

```js
var FramingSocket = require('framing-socket');

// there are actually the defaults
var options = {
    timeout_ms: 5000,                               // Client timeout to use in milliseconds
    frame_length_size: 4,                           // frame_length field size in bytes
    frame_length_reader: function(offset_buffer) {  // custom function to read the frame_length
      return offset_buffer.readInt32BE();           // note that it passes in an OffsetBuffer (see 'offset-buffer' repo)
    }
    rpc_id_reader: function(offset_buffer) {        // custom function to read the rpc_id from the buffer
      return offset_buffer.readInt32BE();           // The frame_length field is stripped from this OffsetBuffer already
    }
};

var socket = new FramingSocket(options);
var rpc_id = 123;                                   // Unique RPC ID to identify this request (unique to this connection)

socket.connect('localhost', 8888).then(function on_connect() {
    return socket.write(rpc_id, new Buffer([0x01, 0x02, 0x03]));
}).then(function on_success(frame) {
    // do something with the returned frame (minus the frame_length bytes)
    // ....
    return socket.close();
}).then(function on_closed() {
    // socket closed
});
```

## Usage

### connect(host, port)
Creates a new socket and returns a promise

```js
framing_socket.connect(host, port).then(function on_connect() {
    // socket is now connected successfully...
}).otherwise(function on_error() {
    // failed to connect
});;
```

### close()
Closes an existing socket and returns a promise.

```js
framing_socket.close().always(function on_close() {
    // socket closed!
});
```

### write(rpc_id, data)
Write data to the socket and returns a promise for the response data.
The RPC ID is used to match the request and response together.

```js
{'fraction_non_alphanumeric': 0.0953267547942655, 'fraction_numerical': 0.00893688326196239, 'mean_word_length': 3.5067114093959733, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '843318', 'n_tokens_mistral': 1515, 'n_tokens_neox': 1441, 'n_words': 582}