質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • Node.js

    1732questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Express

    218questions

    ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

  • Socket.IO

    178questions

    Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

【Express】index.jsで取得したパラメータをwwwに送信したい【socket.io】

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 134

shiro_momo

score 1

Expressを使用したソケット通信に悩んでいます。

routes直下にあるindex.jsで取得したパラメータをbin直下のwwwに送信?する方法がわかりません…

//index.js
// /?uuid=1というパラメータを取得↓
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
  socket.emit("getQaData", {"number":req.query.uuid,});
});

module.exports = router;
///www
var app = require('../app');
var debug = require('debug')('aspen:server');
var http = require('http');
var fs = require('fs');

var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {

    socket.on('getQaData', function(data) {
        io.sockets.emit('confirm', {
          "number":req.number,
        });
    });

});

現状、これではindex.jsからwwwへのパラメータ受け渡しはできず、どうしたものかと悩んでいます…「uuid=1」というパラメータをグローバル変数化すれば行けると思うですがやり方がわからず…

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

以下の変更点で解決いたしました。

・ioをglobal変数化
・index.js内の「getQaData」を「confirm」へ変更

index.js↓

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
  global.io.sockets.emit("confirm", {"number":req.query.uuid});
});

www↓

global.io = require('socket.io').listen(server);
global.io.sockets.on('connection', function(socket) {

    socket.on('getQaData', function(data) {
        global.io.sockets.emit('confirm', {
          "number":data.number,
        });
    });

});

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Socket.ioはたくさんのユーザを待ち受けるサーバの実装方法の一つであり、
Expressもたくさんのユーザを待ち受けるWebサーバの実装方法の一つですよね?

コードの意図は「Socket.ioに繋ぎ、socket引数を生成してからExpressの/にAjax通信でアクセスしてUUIDを確定させる」という事がしたいように見受けられますが、
100人がSocket.ioサーバに押しかけて、100個のsocket変数が生成された後、
ゼロベースで通信した/へのアクセスでUUIDを拾ったとして、どのsocketに紐付ければ良いんですか?

まぁ、この辺は適当に回避しながら作ってみましょうか
大事なのは、オブジェクトを引数とする関数宣言です。

// index.js
// /?uuid=1というパラメータを取得↓
var express = require('express');

// 引数として注入したstatesは何時でも参照出来るようになる
module.exports = states => {
  const router = express.Router();

  router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
    // 対応するsocketを探す
    const socket = state.socketByHash.get(req.query.hash);
    socket.emit("getQaData", {"number":req.query.uuid,});
  });

  return router;
}
///www
const app = require('../app');
const debug = require('debug')('aspen:server');
const http = require('http');
const fs = require('fs');

// 状態を宣言しておく
const states = {
  socketByHash: new Map()
}

// 関数実行を行いstatesを注入
var server = http.createServer(app(states));
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
  // 適当なハッシュ値を生成する、現在時刻とIPアドレス辺りを使えば良いんじゃない?
  const hash = createHash(); // createHash関数は自分で作ってねv
  states.socketByhash.set(hash, socket);
  // ユーザーがAjax通信で指定できるように、利用するハッシュ値は通知しないとだめよ

  socket.on('getQaData', function(data) {
    io.sockets.emit('confirm', {
      "number":req.number,
    });
  });

});

ハッシュ値のアルゴリズムは下記のような記事がありますが、他でユーザーを認識する方法があればそちらを使えば良いかと思います。
Node.jsでSHA1ハッシュを計算する

JavaScriptに於けるオブジェクトは「参照の値渡し」です。
詳しい話は「JavaScript 参照の値渡し」などでググってください。

大事なのはオブジェクトを引数として渡してやると参照渡しのように扱えるので、
index.js内で実際にアクセスが来た時、常に最新のstates.socketByHashを参照出来るというところにあります。

この様にNode.jsでは関数定義という形で、オブジェクトを注入する手法はよく使われるので覚えておいてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/31 19:17

    詳しい解説ありがとうございました。

    前提条件の記載不足で申し訳ありません。
    今回取得するUUIDは「1」「2」「3」「4」の4つと決まっております。(IDの数値は仮です)
    それぞれのIDが割り振られたRFIDタグをリーダに読み込ませ、該当する番号の画像を出しわけるというシステムを作っております。
    リーダからはアルディーノの経由してIDが送信される仕組みです。

    現状、タグを読み取った際に
    index.jsにて

    router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
     console.log(req.query.uuid); //出力結果「1」
    });

    までは得られたが、この「req.query.uuid=1」をどうやったらwwwで参照できるのかしらという悩みでした。

    今回ご教示いただいた方法を私なりにかみ砕き試してみましたが、js自体の初心者という事もあり、いまいち値がどう引き継がれているのかイメージできませんでした。
    機能以前の勉強不足を実感いたしましたので「オブジェクト」や「値渡し」から勉強したいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Node.js

    1732questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Express

    218questions

    ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

  • Socket.IO

    178questions

    Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。