---
lang: ja
path: cookbook/javascript-sdk/chunk-splitting-for-data-stream
labels: クックブック/JavaScript SDK/大きなサイズのデータを送信する
metaTitle: 大きなサイズのデータを送信する | JavaScript SDK｜ クックブック ｜ SkyWay（スカイウェイ）
---

# 大きなサイズのデータを送信する

本ドキュメントでは、SkyWay JavaScript SDK の `DataStream` を使って大きなサイズのデータを送信する方法を説明します。

`DataStream` にて大きなサイズのデータを一挙に送ろうとした場合、 WebRTC の仕様によりエラーとなります。
なお、エラーとなるデータサイズの閾値は、お使いの環境により異なります。

このようなエラーを回避するためには、データを小さなチャンクに分割して送信する処理が必要です。

## Publisher 側でデータを分割する処理の実装例
本ドキュメントでは、サンプルアプリとして公開している [Room ライブラリの P2PRoom による 映像・音声・データの PubSub](https://github.com/skyway/js-sdk/tree/main/examples/p2p-room) をベースとして、巨大な文字列データを送受信する実装を例示します。

前提として、サンプルアプリの HTML コードで以下のようなフォームが記述されています。
このアプリでは、 `write` ボタンを押下するとテキストボックスに入力されている文字列を Subscriber 宛に送信します。

index.html
```html
write dataStream: <input id="data-stream" type="text" />
<button id="write">write</button>
```

[RFC8831](https://www.rfc-editor.org/rfc/rfc8831.html#name-transferring-user-data-on-a) によれば、送信するデータのサイズは最大でも 16KiB にすることが推奨されています。
そのため、 16KiB を超えるような長い文字列を入力し `write` ボタンを押下した場合、パフォーマンス低下や冒頭のエラーによるデータ送信の失敗を引き起こす恐れがあります。

以下は、それらの不具合を回避するために、データを小さなチャンクに分割して送信する処理の実装例です。
手元で動作確認する場合は、サンプルアプリ内の `writeButton.onclick` を以下のコードに書き換えてください。

Room ライブラリの場合 (main.ts)
```ts
import { SkyWayStreamFactory } from '@skyway-sdk/room';

const dataStreamInput = document.getElementById('data-stream') as HTMLInputElement;
const writeButton = document.getElementById('write');

const data = await SkyWayStreamFactory.createDataStream();
writeButton.onclick = () => {
  const chunkSize = 16 * 1024 - 24; // 16KiBから付加情報のサイズ24Byteを引く
  const inputData = dataStreamInput.value;

  // チャンク分割処理
  for (let sentDataSize = 0; sentDataSize < inputData.length; sentDataSize += chunkSize) {
    const chunkData = {
      data: inputData.slice(sentDataSize, sentDataSize + chunkSize),
      eor: sentDataSize + chunkSize >= inputData.length // End of Record
    }
    data.write(JSON.stringify(chunkData));
  }
  dataStreamInput.value = '';
}
```

なお本実装例では、データを分割するだけでなく、各チャンクに付加情報を追加しています。
この付加情報は一連のデータの末尾か否かを示すフラグ `EoR: End of Record` であり、後述するデータ復元処理で利用します。

> なお、SkyWay JavaScript SDK v2.2.0 以前では、データを高頻度に送信した場合にも同様のエラーが発生することがあります。
> この問題に対処するためには、適宜 sleep 処理を入れていただくか、SkyWay JavaScript SDK v2.2.1 以降へアップデートしてご利用ください。

## Subscriber 側でデータを復元する処理の実装例

ここでは、分割されたチャンクから元の文字列を復元する方法を説明します。
なお、本セクションも上記と同様にサンプルアプリ [Room ライブラリの P2PRoom による 映像・音声・データの PubSub](https://github.com/skyway/js-sdk/tree/main/examples/p2p-room) をベースとして実装します。

以下に、データ復元処理の実装例を示します。
手元で動作確認する場合は、サンプルアプリの `subscribeButton.onclick` 内にある `case 'data'` の箇所を以下のコードで書き換えてください。

Room ライブラリの場合 (main.ts)
```ts
subscribeButton.onclick = async () => {
  const { stream } = await me.subscribe(publication.id);

  switch (stream.contentType) {
    // (中略)
    case 'data': {
      const elm = document.createElement('div');
      remoteMediaArea.appendChild(elm);
      elm.innerText = 'data\n';
      // データ復元処理
      let reconstructedData: string = "";
      stream.onData.add((data) => {
        const chunkData = JSON.parse(data as string);
        reconstructedData += chunkData.data;
        if (chunkData.eor) {
          elm.innerText += reconstructedData + '\n';
          reconstructedData = "";
        }
      });
    }
  }
};
```

本実装例では、受信したデータを連結することで元の文字列を復元します。
その上で、 `EoR` が `true` すなわち受信したチャンクが末尾のものであったら、一連の文字列を復元し終えたとして画面に結果を表示しています。
