0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WebSocket Serverで Uncaught SyntaxError: Unexpected token 'o', "[object Blob]" is not valid jsonが出たときの対処法

Posted at

はじめに

去年、私自身がWebRTCハンズオン 本編を使用して、WebRTCの勉強をしていた時につまずいた部分で、今年研究室に入ってきた後輩も困っていたので、改めてエラーの原因を調べました。

発生した現象

エラーが発生した部分

ハンズオン資料のSTEP4 シグナリングサーバを使ってWebRTCをつなげようの部分で、送信用のクライアント端末からシグナリングサーバーにSDPを送信します。その後、シグナリングサーバーはSDPを受信用のクライアント端末に転送します。この転送されたSDPを受信用のクライアント端末が解析する際にエラーが発生します。

現象

受信用のクライアント端末で文字列をJSONとして解析する部分で、Uncaught SyntaxError: Unexpected token 'o', "[object Blob]" is not valid jsonというエラーが発生する。

このエラーは「[object Blob] という文字列が有効なJSON形式の文字列でない。」という意味です。[object Blob] というのはバイナリデータのBlobオブジェクトが文字列型にキャストされたデータを指します。

String(new Blob([0]))
//'[object Blob]'

要するに、JSON形式のテキストデータが届くはずのところにバイナリデータが届いてしまっているために発生するエラーです。

状況

WebSocketの通信をwiresharkを使用してキャプチャしたところ

  • 送信用のクライアント端末 -> シグナリングサーバーはテキストデータとして送信されている

string.png

  • シグナリングサーバー -> 受信用のクライアント端末はバイナリデータとして送信されている

binary.png

対処方法

signaling.jsを下記のように書き換える。

signaing.js
"use strict";

const WebSocketServer = require("ws").Server;
const port = 3001;
const wsServer = new WebSocketServer({ port: port });

wsServer.on("connection", function (ws) {
    console.log("-- websocket connected --");
    ws.on("message", function (message, isBinary) {
        wsServer.clients.forEach(function each(client) {
            if (isSame(ws, client)) {
                console.log("- skip sender -");
            } else {
                client.send(message, { binary: isBinary });
            }
        });
    });
});

function isSame(ws1, ws2) {
    // -- compare object --
    return ws1 === ws2;
}

console.log("websocket server start. port=" + port);

原因

node.jsのWebSocketモジュール仕様変更が原因で起こるエラーでした。

現在のWebSocket Serverは、データを受信する際、第一引数に受信したデータをバイナリデータとして、第二引数にバイナリデータであるかどうかのフラグをコールバック関数に渡します。

仕様変更前は、テキストメッセージを受信した際にWebSocket Serverが内部でUTF-8にデコードする動作を行っていたため、binary引数を指定する必要がありませんでした。現在はデコード処理が無駄とされており、binary引数を渡すことでデコードせずに文字列型のデータとして送信できるようになっています。

binary引数を省略すると、シグナリングサーバーはデータをバイナリデータとしてクライアントに送信してしまいます。その結果、受信用のクライアント端末は文字列型を想定していたところにBlobオブジェクトが届いてしまって、エラーが発生していました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?