WebSocketシリーズの文字列はどうやってバイナリデータと相互に変換されますか?


概要
前のブログでは、どのようにデジタルタイプ(例えば、Shot、Int、Longタイプ)をJavaScriptでバイナリ変換するかについて話しましたが、興味があれば、本シリーズの第二編ブログ、WebSocketシリーズのJavaScriptでは、デジタルデータはどうやってバイナリデータに変換されますか?今回は、stringタイプのデータはどのように処理しますか?本稿はWebSocketシリーズの第三編で、主にstringデータとバイナリデータの変換方法を紹介します.具体的な内容は以下の通りです.
  • JavaScriptにおけるstringタイプ基礎知識
  • JavaScriptはどのようにstringタイプをバイナリデータ
  • に変換しますか?
  • JavaScriptが、バイナリデータをどのようにstringタイプに変換するかは、本明細書ではWebSocketとあまり関係がないが、WebSocketでバイナリデータを伝えるための基礎知識として準備されているので、このシリーズに入れられている.もし読者がWebSocketについてよく知らないならば、あるいはその使用シーンと詳細については分かりません.私のシリーズの最初のブログであるWebSocketシリーズの基礎知識入門編を読むことができます.
  • stringタイプの基礎知識
    stringというタイプはJavaScriptをよく知っている学生にとってはよく知らないはずです.JavaScriptの中の基礎データの種類の一つです.でも、今日はまずDOMStringを紹介します.
    DOMStringはUTF-16文字列です.JavaScriptはすでにこのような文字列を使用しているので、DOMStringはそのままStringにマッピングされます.nullをDOMStringを受ける方法やパラメータに渡すと、通常は「null」に変換されます.
    WebSocketでstringタイプのデータ転送を行う場合に使用されるのも実はDOMStringです.しかし、MDNにおけるDOMStringの紹介によれば、ほとんどの日常的な使用シーンにおいては、DOMStringは一つのストリングタイプであると考えられていることが分かる.ですから、私たちはこのタイプを知るだけで、使う時はやはりstringタイプとして処理すればいいです.
    コーディング
    以上のようにUTF-16に言及しましたので、UTF-16とバックエンドによく使われているUTF-8の二つのコードを簡単に紹介します.なぜコードの種類を紹介する必要がありますか?バックエンドと文字列データの転送を行う時、使用可能な符号化方式が違っていますので、お互いに異なるデータが得られます.したがって、私たちは、stringのバイナリデータ通信を行うには、文字列をバイナリに変換するだけでなく、合意したstring符号化を協議する必要があります.
    UTF-16
    UTF-16(16-bit Unicode Trans formation Format)は、ユニフォーム文字符号化五段階モデルの第三層:文字符号表(Chracter Ecoding Form)の一実施形態である.Unicode文字セットの抽象的なコードビットを16ビットの長さの整数(すなわちシンボル)のシーケンスにマッピングし、データ記憶または転送に使用する.
    Unicode文字の符号ビットは、1つまたは2つの16ビットの長いシンボルが必要であるため、これは長くなる表現である.
    UTF-16は、JavaScriptにおけるstring符号化タイプである.
    UTF-8
    UTF-8(8-bit Unicode Trans formation Format)はユニックの可変長文字コードであり、プレフィックスコードでもあります.これは、Unicode規格における任意の字元を表し、その符号化の最初のバイトは依然としてASCIIと互換しています.これにより、元のASCII字元を処理するソフトウェアは、少なくとも部分的に修正する必要がなくても、そのまま使用できます.UTF-8は1バイトから4バイトの各文字コードを使用しています(2003年11月再規格).
    UTF-8は多くの言語で使用される汎用コードタイプであり、バックエンドアプリケーションでは非常に一般的である.
    JavaScriptのUTF 16とUTF-8はどうやって符号化変換しますか?
    Githubには変換ライブラリGitHub-dcodeIO/utfx:A copact library to encode,decode and convert UTF 8/UTF 16 in JavaScriptがあります.このライブラリを通じて、UTF-8符号化とUTF-16符号化に文字列を変換することができます.このライブラリの具体的な原理と内容、そして二つのコード方式の詳細については、次のブログで説明します.簡単に紹介します.使い方です.
    import utfx from './util/utfx';
    
    let str = 'abcdefg';
    let result = [];
    
    function stringSource(s) {
        let i = 0;
        return function () {
            return i < s.length ? s.charCodeAt(i++) : null;
        };
    }
    
    utfx.encodeUTF16toUTF8(stringSource(str), function (b) {
        result.push(b);
    }.bind(this));
    同様に、このクラスは他の方法を提供する.
  • decodeUTF8toUTF16は、UTF-8のstringデータをUTF-16のstringデータに変換する.
  • calculateUTF16asUTF8は、UTF-16の符号化されたstringタイプがUTF-8に変換された後に占めるByte長を計算する.この二つの方法は後の章でも使われます.
  • JavaScriptはどのようにstringタイプをバイナリデータに変換しますか?
    JavaScriptにおけるstringタイプの符号化とUTF-8とUTF-16の間の符号化方式を理解しました.次に、stringタイプをバイナリデータに変換する方法を説明します.まず、バックエンドと対話するときに使用する符号化方式はUTF-8であると仮定し、より多くの使用シーンを満たすことができる.UTF-16がそのまま使用されているなら、変換符号の論理を無視すれば良い.構想を簡単に紹介します.変換が必要な文字列を得たら、まずその長さを知ってから、アラーBufferの中の関連パラメータを初期化して、データをArayBufferに入れてもいいです.上記の例を少し変えます.
    import utfx from './util/utfx';
    
    function stringSource(s) {
        var i = 0;
        return function () {
            return i < s.length ? s.charCodeAt(i++) : null;
        };
    }
    
    let str = 'abcdefg';
    
    let strCodes = stringSource(str);
    let length = utfx.calculateUTF16asUTF8(strCodes)[1];
    let buffer = new ArrayBuffer(length + 4); //       UTF8        +4 Byte       
    let view = new DataView(buffer);
    let offset = 4;
    
    view.setUint32(0, length); //             
    
    utfx.encodeUTF16toUTF8(stringSource(str), function (b) {
        view.setUint8(offset++, b);
    }.bind(this));
    上記の例により、UTF-8に従ってバイナリデータを符号化してArayBufferに入れたが、その長さをUnisigned Intタイプとしてバイナリヘッダ4個のByteの位置に記憶した.
    JavaScriptはどうやってバイナリデータをstringタイプに変換しますか?
    どのようにしてstringタイプをバイナリデータに変換するかが分かりました.以下はどうやって全体のデータをバイナリから読み取って、stringタイプに変えますか?上の2進数に変換する過程によって、関連する2進数のstringタイプの方法を思い付きにくくありません.具体例は以下の通りです.
    import utfx from './util/utfx';
    let str = 'abcdefg';
    
    function stringSource(s) {
        var i = 0;
        return function () {
            return i < s.length ? s.charCodeAt(i++) : null;
        };
    }
    
    let strCodes = stringSource(str);
    let length = utfx.calculateUTF16asUTF8(strCodes)[1];
    let buffer = new ArrayBuffer(length + 4); //       UTF8        +4 Byte       
    let view = new DataView(buffer);
    let offset = 4;
    
    //           
    view.setUint32(0, length); //           
    
    utfx.encodeUTF16toUTF8(stringSource(str), function (b) {
        view.setUint8(offset++, b);
    }.bind(this));
    
    //           
    let Strlength = view.getUint32(0);
    offset = 4;
    let result = []; // Unicode    
    let end = offset + Strlength;
    
    
    utfx.decodeUTF8toUTF16(function () {
        return offset < end ? view.getUint8(offset++) : null; //   null         
    }.bind(this), (char) => {
        console.log(char)
        result.push(char);
    });
    
    let strResult = result.reduce((prev, next)=>{
        return prev + String.fromCharCode(next);
    }, '');
    上記の例から分かるように、前の4つのByteで文字列の長さを読み取ってから4番目のBytte(0から計算します)の位置から指定された長さの文字列の文字コードを読み出すだけでいいです.最後に、私たちはUnicodeコード配列を得ました.fromCharCode方法だけで文字列に変換できます.
    締め括りをつける
    ArayBufferとDataViewを使うことによって、stringデータとバイナリデータの中で相互に変換することができます.stringタイプの転換に関する基礎ができたら、読者は後のWebSocketでバイナリデータの転送を行う時に関連する内容と処理ロジックを理解することができます.次のWebSocketシリーズに関するブログでは、Websocketを通じて、バックエンドにバイナリデータを送る方法と、WebSocketで受信したバイナリデータをどう処理するかを紹介します.興味のある学生は引き続き関心を持つことができます.