shuhelohelo’s blog

Xamarin.Forms多めです.

Chrome拡張 : Content ScriptからSignalRを使ってサーバーに接続

前回まででContent ScriptでjQueryを使えるようにした.

shuhelohelo.hatenablog.com

今回はContent ScriptからSignalRを使えるようにする.

SignalRのJavaScriptライブラリを取得

JavaScriptのSignalRはnpmで取得できる.

www.npmjs.com

npmを使うためにnode.jsをインストールする.

npmコマンドでsignalrをインストールする.

npm i @microsoft/signalr

npmについて全然わかっていないのですごく適当だけど,上記コマンドを実行するとカレントディレクトリにnode_modulesというフォルダが作成され,その中に@microsoft/signalrフォルダが作成される.

SignalRライブラリをChrome拡張機能に導入する

このsignalrフォルダをChrome拡張機能のフォルダにコピーする.

signalr/dist/browser/signalr.min.jsをmanifest.jsonに追加する.

{
    "manifest_version":2,
    "name":"Content Script Basic",
    "description": "Content Scriptの最小限の構成を確認する",
    "version": "1.0.3",
    "content_scripts": [
        {
          "run_at":"document_end",
          "matches": ["<all_urls>"],
          "js": ["jquery-3.4.1.min.js","signalr/dist/browser/signalr.min.js","content_script.js"]
        }
      ]
}

SignalRでサーバーに接続する

content_script.jsに以下の内容を記述する.

内容は以前に書いたSignalR通信の記事とほとんど同じで,サーバー側からのメッセージを受け取るだけ

shuhelohelo.hatenablog.com

$(async function () {
    const connection = new signalR.HubConnectionBuilder()
        .withUrl('https://localhost:44350/chathub')//signalRのhubを指定すること
        .withAutomaticReconnect({
            nextRetryDelayInMilliseconds: retryContext => {
                return Math.random() * 10000;
            }
        })
        .build();

    //接続が切れたとき
    connection.onclose(function (message) {
        console.log("closed");
    });

    //(再)接続中
    connection.onreconnecting(function (message) {
        console.log("connecting");
    });

    //再接続完了
    connection.onreconnected(function (message) {
        console.log("connected");
    });

    //サーバーからのメッセージ受信時の処理
    connection.on('receive', function (message, from) { //サーバー側からこのreceiveが呼び出されたときに実行されるfunctionを登録する
    });

    //接続開始
    await connection.start();
});

試してみる

サーバーが動いていて,withUrlでのURLの指定が正しければ,この自作拡張をインストールしてウェブページを開いた際に接続が行われる.

ブラウザの開発者モードでConsoleへの出力を見てみると,以下のように接続が確立されていることが確認できる.

f:id:shuhelohelo:20191123095104p:plain

ちなみに,サーバー側は以下のようにメッセージを中継するだけの簡単なもの.

    internal class ChatHub : Hub
    {
        public async Task Send(string message, string from)//2つのstringを受け取る
        {
            await Clients.All.SendAsync("Receive", message, from);
        }

        public async Task SendObject(Message message)
        {
            await Clients.All.SendAsync("ReceiveObject", message);
        }
    }