2016-05-20 17 views
2

ご迷惑をおかけください、私は学んでいます。 :)ルート/ HerokuでNode.JSのSocket.IOを正しく使用するには?

私は私のルートの中でio.sockets.emitを使うことができるようにSocket.IOを設定しました。いくつかの問題があります。

  1. (解決しよう?EDIT 3を参照)を使用するには、私は言葉socketで始めることはできません。私はioで始まらなければなりません。あるいは、 "ReferenceError:socket is not defined。" socket.broadcast.emitを使用して、現在のユーザー以外のすべてのクライアントにイベントを送信したいと考えています。今現在、私は、クライアント側で、現在のユーザーであれば、イベントを実行しないようにチェックする必要があります。プロジェクトが進行するにつれ、より多くのイベントを発行する必要があります。

  2. (解決しよう、EDIT 1 & 2参照)私はnode app.jsでアプリケーションを実行して手動で私は、サーバー側の変更を加えるたびに、サーバーを再起動する必要があります。 nodemonを実行すると、「ポート3000はすでに使用中です。」というメッセージが表示されます。私はHerokuのを押すと、私はビン/ WWW 80に3000から変更次のコードからポートを有する(SOLVED、EDIT 2を参照)、これは以下...

  3. に関連しなければならないことを感じるとapp.jsでも動作しません(コンソールのソケットには404エラーが表示されます)。これと#2が両方の場所でhttp /ポートを処理することによって発生する場合、これを正しく設定するにはどうすれば、node app.jsはなぜ機能しますか?

  4. 以下のルート(戦場)でSocket.IOを実行する必要があります。私はすでにrequire('./routes/battlefield')(io)でこれをやっていますか?

ビン/ WWW

var app = require('../app'); 
var port = normalizePort(process.env.PORT || '3000'); 
app.set('port', port); 
var server = http.createServer(app); 
server.listen(port); 

app.js

var app = express(); 
var http = require('http').Server(app); 
http.listen(3000); 
var io = require('socket.io')(http); 

app.set('socketio', io); 
var battlefield = require('./routes/battlefield')(io); 

battlefield.js

var express = require('express'); 
var router = express.Router(); 

var returnRouter = function(io) { 
    router.get('/', function(req, res, next) { 
    // other stuff 
    io.sockets.emit('message', 'This works'); 
    socket.broadcast.emit('message', 'Socket is undefined'); 
    }) 
    return router; 
}; 
module.exports = returnRouter; 

私が使用できるようにするio.on('connection', function (socket) {で私のルートをラップしようとしたsocket 、および代わりに'Socket is undefined'イベントは発生しません。

var returnRouter = function(io) { 
    io.on('connection', function (socket) { 
    router.get('/', function(req, res, next) { 
     // other stuff 
     socket.emit('message', 'This is never emitted'); 
    }) 
    }) 
    return router; 
}; 

私はこのような長い質問をお詫び申し上げます。助けてくれてありがとう!


EDIT1:この質問を書き出すは私が問題をよりよく理解して助けました。私はserver.listen(port);を私のbin/wwwとnodemonで今すぐ動作するとコメントしました。しかし、アプリはHerokuでクラッシュします。私のProcfileはweb: node ./bin/www ...変更する必要がありますか?

EDIT2: EDIT1とグーグルのビットを考え出すした後、私は私がserver.listen();(ビン/ WWW)http.listen(3000);(app.js)を持つことができないことがわかりました。

bin/wwwでは、server.listen();を削除しました。

わかりやすくするために、var http = ...をvar server = ...に変更し、bin/wwwから取得したprocess.env.PORT || '3000';をリッスンしました。それが何もしていないように見えるので、私はまたapp.set('socketio', io);を削除...それはなぜそこにあったのだろうか。

app.js

var app = require('express')(); 

var server = require('http').Server(app); 
var io = require('socket.io')(server); 
var port = process.env.PORT || '3000'; 
server.listen(port); 

はこれも万歳、理由process.env.PORTのHerokuの作業になります!私はapp.jsでアプリを初期化していたので、node app.jsが働いていたと思います。私はbin/wwwが実行されていないと思いますか?

私はまだ#1(socket.broadcast.emitを使用)で助けが必要です。

EDIT 3:私は文字通り一日一杯になりましたが、私はそれを1つの奇妙なものと考えました。もちろん、私はsocketを使用できませんでした。これはconnectで指定されたパラメータです。私はまた、異なるルートを介してソケットにアクセスする必要があり、見つけたthis SO question。これは私がbattlefield.jsにやってしまったものです:

var returnRouter = function(io) { 
    var socket; 
    router.get('/', authenticatedUser, function(req, res, next) { 
    io.on('connection', function(client){ 
     socket = client; 
    }); 

    // other stuff 
    res.render('battlefield', {/* data */}); 
    setTimeout(function(){socket.emit('test', 'It works!')}, 500); 
    }); 

    router.post('/', function(req, res, next) { 
    // socket can be accessed 
    }); 
    return router; 
}; 
module.exports = returnRouter; 

は(注:私はこれをコピーして準備ができpasteableされている場合ので、私は知らない私自身のコードの多くを取って、あなたはおそらくチェックする必要がありますそのソケットはnullではありません)

setTimeoutが指定されていないと、ソケットはGET '/'で定義されていません。私の理解では、ページは最初にレンダリングする必要があります... 200は時々私のために働かないと500は奇妙です。私は500でそれを残すことができますが、これはゲームのために時間がかなり重要です。


私の質問は次のようになります。

はこれが改善することができる/私はsetTimeoutをせずにこれを行うことができます方法はありますか?私はこのコードとクライアントを正しく接続していますか?Socket.IOを効率的に使用していますか?

P.これらの質問に誰も答えなければ、私はこれを編集し、質問に答えて、最良の答えとして私の答えを受け入れるでしょう。

答えて

2

Nodeでルーティングを行うときにソケットを使用すると便利ではありません。

別の名前空間(例:www.example.com - > www.example.com/some-name-space)に移動すると、フロントエンド変数が削除され、再送信する必要があります。これは、その名前空間のGET要求と共にオブジェクトを渡すと効果的です。しかし、ソケットは必要ありません。ソケット用ルーターファイル

var canAlsoBePassed = {some: "things"}; 
router.get('/', function(req, res, next) { 
    res.render('index', { items: "Can be passed directly", variables: canAlsoBePassed }); 
}); 

アプリケーションの最高の種類に次のように行わ

その1ページのアプリのためのものであるか、AJAX要求を交換します。ソケットが可能にするもう1つの大きな点は、クライアントが情報を要求することなくサーバーが情報をプッシュできることです。

SetTimeoutについてのご質問にお答えするために、これは必要ありません。

クライアント側で実行されているソケットスクリプトがドキュメントの読み込みを待機していることを確認してください。

$(document).ready(function() { 

io.on(サーバー側の「接続」イベントの火災は、あなたが奉仕する新しいクライアントを持って知っている。

は、サーバー側から作る歓迎イベントのようなものを、イベントを発しますクライアントは、特定のルームに参加。あなたはその部屋でそれらを持っていたら、あなたはその部屋に放出されたすべてのイベントをリスニングすることができます。

カスタム名前空間 は、カスタム名前空間を設定するにはsocket.io公式情報を参照してください、あなたはできる サーバー側での関数の呼び出し:

var nsp = io.of('/my-namespace'); 
nsp.on('connection', function(socket){ 
    console.log('someone connected'): 
}); 
nsp.emit('hi', 'everyone!'); 
On the client side, you tell Socket.IO client to connect to that namespace: 

var socket = io('/my-namespace'); 

は、あなたの質問に最も正確な答えではないかもしれないが、私はそれが正しい方向にあなたをプッシュしたいと考えています。

関連する問題