1
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?

More than 1 year has passed since last update.

Webの勉強はじめてみた その32 〜AJAXとWebSocket〜

Posted at

N予備校「プログラミング入門Webアプリ」を受講しています。
今回は第4章9,10節です。

AJAX

Asynchronous JavaScript + XML
クライアント-サーバー間で、非同期に通信が行える。

複数ページで実装していたサイトを単一のページで複数の機能(AJAXやWebSocket)を表現したアプリケーションを、シングルページアプリケーション(SPA)という。

app.js
const serverStatus = require('./routes/server-status');
app.use('/server-status', serverStatus);
app/entry.js
const loadavg = $('#loadavg');

setInterval(() => {
  $.get('/server-status', {}, (data) => {
    loadavg.text(data.loadavg.toString());
  });
}, 10);
routes/server-status.js
'use strict';
const express = require('express');
const router = express.Router();
const os = require('os');

router.get('/', (req, res, next) => {
  res.json({ loadavg: os.loadavg() });
});

module.exports = router;

ちょっとわかりにくい。

json形式はJavaScriptのオブジェクトの書き方ができるので、{loadavg: os.loadavg()}となる。

最初にapp.js が読み込まれ、 /server-statusにアクセスされると、server_status.jsが呼び出される。
なお、server-status.jsgetは、自分のことを指すので /になる。
server-status.jsres.jsonの値がentry.jsdataに格納される。

ポーリング

クライアントからサーバーに対して一定間隔に情報を取得する実装方法

今回みたいな10ミリ秒はかなり負荷がかかる。

ロードアベレージ

1 CPU における単位時間あたりの実行待ちとディスクI/O待ちのプロセス数

1を超えるとビジー状態。

同一生成元ポリシー(Same-Origin Policy)

ブラウザのセキュリティ上の考え方で、 コンテンツが同一の生成元から提供されているかを確認し、外部からの干渉を防ごうとするポリシー

今回でいうと、

スキーム: http
ホスト: localhost
ポート: 8000

この三つが同じでないとAJAXでは弾かれる
同一生成でない領域へのアクセスのことをクロスオリジンリクエストという。

WebSocket

Webサーバーとブラウザ間で利用できる双方向通信の規格
リアルタイムを優先するなら、AJAXよりもWebSocket。

プル通信: 常にクライアントがサーバーに情報を要求する(AJAX)
プッシュ通信: クライアントだけでなく、サーバーからも任意のタイミングでクライアントに情報を送信できる(WebSocket)

リクエストがあると、接続を維持し続ける。

Socket.IO を利用する

yarn add socket.io@2.1.1 socket.io-client@2.1.1

サーバー側

bin/www
var server = http.createServer(app);
const io = require('socket.io')(server);
const os = require('os');

function emitServerStatus(socket){
  socket.emit('server-status', {loadavg: os.loadavg()});
  console.log(`server-status event emitted.`);
}

io.on('connection', function(socket){
  setInterval(emitServerStatus, 10, socket);
});

クライアント側

app/entry.js
const loadavg = $('#loadavg');

import io from 'socket.io-client';
const socket = io('http://localhost:8000');
socket.on('server-status', (data) => {
  loadavg.text(data.loadavg.toString());
});
socket.on('connect', () => {
  console.log('接続しました');
});
socket.on('disconnect', () => {
  console.log('切断しました')
});

connection イベントは、クライアントから接続要求があったときに発生する。

socket.emit('server-status', {})
全てのクライアントに向けて、server-statusというイベントを発生させる。

まとめ

AJAXは以前にも何回か使ったことはあるけれど、WebSocketははじめて。サーバーを閉じて接続を切断した時にもクライアントが延々と情報を送り続けようとするのをみても、単純にどっちがいいってこともなさそう。
しかしexpressにまだ慣れてないのもあって、どこに何を書けばいいのかというのがぱっと判断できないのが悩み。

1
0
2

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
1
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?