メソッド「POST」で送信された画像をNode.jsを使ったサーバにより受け取り、接続されているクライアントにSocket.ioで画像を通知して、画像を表示します。なお開発環境は、Visual Studio Codeを使用します。

ライブラリの準備

expressを次のコマンドでインストールします。

npm i --save express

socket.ioをを次のコマンドでインストールします。

npm i --save socket.io

Advanced REST client」により、POSTメソッドを用いて画像を転送します(「LaravelでRestfulなインタフェースの実装」参照)。

アプリの作成

メソッド「POST」で送られた画像をブラウザに表示するアプリを次に示します。

Node.jsで作成したサーバアプリ「server.js」を次に示します。

  • 11行目でSocket.ioを使ってクライアントと接続します。
  • 13行目でクライアントのブラウザに表示するデータを取得します。
  • 14行目で「Advanced REST client」からの画像を受け取ります。
  • 29行目で「io.sockets.emit」メソッドを使って、イベント名「new message」に送信します。

server.js

'use strict';

const fs = require('fs');
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const express = require('express');
const PORT = process.env.PORT || 3000;
app.use(express.static(__dirname));

io.on('connection', (socket) => console.log('a user connected')); //socket.ioのコネクション

app.get('/', (req, res) => res.sendFile('./index.thml'));
app.post('/', (req, res) => {
    let buffers = [];
    let cnt = 0;

    req.on('data', (chunk) => {
        buffers.push(chunk);
        console.log(++cnt);
    });

    req.on('end', () => {
        console.log(`[done] Image upload`);
        req.rawBody = Buffer.concat(buffers);  //書き込み
        fs.writeFile('./img.jpeg', req.rawBody, 'utf-8', (err) => {
            if (err) return;
            console.log(`[done] Image save`);
            io.sockets.emit('new message', { message: `[done] Image save` }); //画像が更新されたことを通知
        });
        res.end();
    });
});

http.listen(PORT, () => console.log(`listening on *:${PORT}`));

Node.jsで作成したSocketioアプリ「app.jsl」を次に示します。

  • 13行目でサーバアプリ「server.js」からイベント名「new message」のメッセージを受信します。受信すると6行目の「draw」を呼び出し受信したファイルをChromeに表示します。

public/app.js

'use strict';

const stage = new createjs.Stage('myCanvas');
const socket = io();

const draw = () => {
    const bmp = new createjs.Bitmap(`/img.jpeg?date=${new Date()}`);
    stage.addChild(bmp);
    createjs.Ticker.on('tick', () => stage.update());
    console.log(`update: ${new Date()}`);
}

socket.on('new message', (msg) => draw());

draw(); //初期実行

Node.jsで作成したクライアントアプリ「index.html」を次に示します。

  • 11行目でインストールしたsocket.ioを指定します。インストールされたフォルダ「node_modules」の構成を次に示します。
G:.
│  img.jpeg
│  index.html
│  package-lock.json
│  package.json
│  server.js
│
├─node_modules
│  │  .package-lock.json
│  │
│  ├─.bin
│  │      mime
│  │      mime.cmd
│  │      mime.ps1
│  │      node-gyp-build

・・・
│  │
│  ├─socket.io
│  │  │  LICENSE
│  │  │  package.json
│  │  │  Readme.md
│  │  │  wrapper.mjs
│  │  │
│  │  ├─client-dist
│  │  │      socket.io.esm.min.js
│  │  │      socket.io.esm.min.js.map
│  │  │      socket.io.js
│  │  │      socket.io.js.map
│  │  │      socket.io.min.js
│  │  │      socket.io.min.js.map
│  │  │      socket.io.msgpack.min.js
│  │  │      socket.io.msgpack.min.js.map
│  │  │
│  │  ├─dist
│  │  │      broadcast-operator.d.ts
│  │  │      broadcast-operator.js
│  │  │      client.d.ts
│  │  │      client.js
│  │  │      index.d.ts
│  │  │      index.js
│  │  │      namespace.d.ts
│  │  │      namespace.js
│  │  │      parent-namespace.d.ts
│  │  │      parent-namespace.js
│  │  │      socket.d.ts
│  │  │      socket.js
│  │  │      typed-events.d.ts
│  │  │      typed-events.js
│  │  │      uws.d.ts
│  │  │      uws.js
│  │  │
│  │  └─node_modules
│  │      ├─debug
│  │      │  │  LICENSE
│  │      │  │  package.json
│  │      │  │  README.md
│  │      │  │
│  │      │  └─src
│  │      │          browser.js
│  │      │          common.js
│  │      │          index.js
│  │      │          node.js
│  │      │
│  │      └─ms
│  │              index.js
│  │              license.md
│  │              package.json
│  │              readme.md
│  │
│  ├─socket.io-adapter
│  │  │  CHANGELOG.md
│  │  │  LICENSE
│  │  │  package.json
│  │  │  Readme.md
│  │  │
│  │  └─dist
│  │      │  index.d.ts
│  │      │  index.js
│  │      │
│  │      ├─cjs
│  │      │      index.d.ts
│  │      │      index.js
│  │      │
│  │      └─es
│  │              index.d.ts
│  │              index.js
│  │
│  ├─socket.io-parser
│  │  │  CHANGELOG.md
│  │  │  LICENSE
│  │  │  package.json
│  │  │  Readme.md
│  │  │
│  │  ├─dist
│  │  │      binary.d.ts
│  │  │      binary.js
│  │  │      index.d.ts
│  │  │      index.js
│  │  │      is-binary.d.ts
│  │  │      is-binary.js
│  │  │
│  │  └─node_modules
│  │      ├─debug
│  │      │  │  LICENSE
│  │      │  │  package.json
│  │      │  │  README.md
│  │      │  │
│  │      │  └─src
│  │      │          browser.js
│  │      │          common.js
│  │      │          index.js
│  │      │          node.js
│  │      │
│  │      └─ms
│  │              index.js
│  │              license.md
│  │              package.json
│  │              readme.md
│  │
│  ├─statuses
│  │      codes.json
│  │      HISTORY.md
│  │      index.js

・・・

│              subprotocol.js
│              validation.js
│              websocket-server.js
│              websocket.js
│
└─public
        app.js

index.html

<html>

<head>
    <meta charset="utf-8" />
    <title>TomoSoftApp</title>
</head>

<body style="background-color:#D0D0D0;">
    <canvas id="myCanvas" width="640" height="480" style="background-color:#FFFFFF;"></canvas>
    <script src="https://code.createjs.com/easeljs-0.8.2.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script src="/public/app.js"></script>
</body>

</html>

アプリの実行

次の手順で作成したアプリを実行します。

  1. Visual Studio Codeのエクスプローラーから「server.js」ファイルを選択し、「実行」メニューから「デバッグの開始」を選択します。
  2. ChromeでURL「http://localhost:3000/」を設定して、サーバアプリにアクセスします。
  3. Chromeのアプリ「Advanced REST client」を起動して次のように設定します。
  4. 表示されている「CHOOSE A FILE」ボタンをクリックして、「img.jpeg」ファイルを選択して(注:ファイル名は固定)、「SEND」ボタンをクリックします。
  5. 次のように、Visual Studio Codeのデバッグコンソールにファイルが保存されたことが表示されます。
  6. 次のように、Chromeに「Advanced REST client」から送信したファイルが表示されます。