Electronのメインプロセスをローカルサーバー化して外部からアクセスする

TechAcademyでメンターをしています

この内容はパッケージのアップデートなどにより古くなっている可能性があります。

投稿時点で最新の情報を記載していますが、各パッケージのアップデートにより上手く動作しない可能性もあります。実用可能かどうかは十分なテストの上お試しください。

YouTubeのチャットを拾って参加型配信の予約を受け入れ、それを画面に表示するという物を作ったのですが、そのときに配信ソフトから予約状況を表示させるために、Electronをローカルサーバーとしてアクセスできないかと悪戦苦闘したので書き残します。

この記事の目次

外部からのアクセスが不要なら何もする必要は無い

普通にアプリ内完結の動作であれば当然のように動きますので、特段何もする必要はありません。

今回の場合は、メインプロセスが吐き出す情報やSocket IOの通信を利用して、配信ソフトのブラウザソースとして表示させる事で目的を実現したかったため、ローカルサーバー化させる必要が出てきました。

一応他の対応方法もある

外部からアクセスさせない方法として、クロマキーとして合成するように背景色を指定した画面をElectronアプリからポップアップさせ、ウィンドウキャプチャーとする方法もあります。

今回この方法を避けたのは、以下の理由からです。

  • スタイルを変えたいと思ったときに対応しづらい
  • サイズなどの調整をしづらい
  • 余計なウインドウが開く

直に配信ソフトのブラウザソースとすれば、CSSに依る調整が可能になるのでとても理想的です。

具体的な方法

ちょっと冗長な部分がありそうな気がしますが、ポイントはこの辺です。

const http = require("http");

const server = http.createServer();
server.on("request", (req, res) => {
  let reqpath = req.url;
  if (reqpath === "/") {
    reqpath = "/index.html";
  }

  let stream = fs.readFileSync(path.join(__static, reqpath));
  let ext = reqpath.substr(reqpath.lastIndexOf(".") + 1);
  res.writeHead(200, {
    "Content-Type": mime.getType(ext),
    "Access-Control-Allow-Origin": "*",
  });
  res.end(stream);
});

const PORT = 8081;

const io = require("socket.io")(server, {
  cors: {
    origin: "*",
  },
});

server.listen(PORT);

ちょっとアレコレしてから時間が経ってしまって細かく何の為に何を書いたのかというのが微妙なのですが、コレをメインプロセスに記載します。

httpを使うところと、環境変数でstaticを利用する事やCORS対応あたりがポイントかと思います。

コレを終えたあと io.on でイベントを拾ってあげればSocket IOも使えます。

注意点

この方法そのままだとブラウザからもアプリの画面を呼び出せます。

なので、完全に切り分ける必要があるという時には、もう少し対応が必要かなと言う所です。
それでも、ブラウザからアクセスできるのは便利! おかげで必要な事が実装できました。

ということで、シンプルながら誰かの助けになれば。

この記事を書いた人

ささぴよ

TechAcademy公認エバンジェリスト
株式会社シノビアシ 取締役副社長 兼 CTO

中学時代に買ってもらったPerforma 550以降ずっとアップル製品漬けの人生。iPhoneは日本上陸時から愛用し続けている。
「誰かが作っているなら、自分でも作れるはず!」という安易な発想からHP制作などを始め、ネットの世界から情報を集めてひたすらいろんなことをやってみるようになった。

TechAcademyでは、Webデザイン / WordPress / UI/UX / Node.js / OSS活動 / デザイン実践ポートフォリオ / フリーランスサポートのコース を担当するメンター。

よく歌って踊っている。