Bitte entschuldigen Sie alle noobiness, ich lerne. :)Wie wird Socket.IO in Node.JS ordnungsgemäß für die Verwendung in Routen/mit Heroku verwendet?
Ich habe Socket.IO eingerichtet, so dass ich io.sockets.emit innerhalb meiner Routen verwenden kann, und ich habe das funktioniert. Es gibt ein paar Probleme.
(GELöST? SEE EDIT 3) nutzen zu können, kann ich nicht mit dem Wort
socket
starten. Ich muss mitio
beginnen oder ich bekomme "ReferenceError: Socket ist nicht definiert." Ich würde gernesocket.broadcast.emit
verwenden können, um das Ereignis an alle Clients mit Ausnahme des aktuellen Benutzers zu senden. Im Moment muss ich auf der Client-Seite überprüfen, ob das Ereignis ausgeführt wird, wenn es der aktuelle Benutzer ist, und es wird zu einem echten Problem, da ich während des Projektfortschritts mehr Ereignisse ausgeben muss.(GELÖST, SEE EDIT 1 & 2) Ich habe die Anwendung mit
node app.js
und starten Sie den Server jedes Mal manuell I eine serverseitige Änderung vornehmen laufen. Wenn ich nodemon ausführen, bekomme ich "Port 3000 wird bereits verwendet." Ich glaube, dass dies auf die folgende Beziehung gesetzt werden müssen ...(GELÖST, SEE EDIT 2) Wann Heroku schieben, ich habe den Port aus dem Code unter 3000-80 in bin/www geändert und app.js, aber es funktioniert nicht (ich kann einen Fehler 404 für Sockets in der Konsole sehen). Wenn dies und # 2 durch den Umgang mit http/Ports an beiden Orten verursacht werden, wie kann ich dies richtig einrichten und warum funktioniert
node app.js
?Ich muss Socket.IO nur auf der unten gezeigten Route (Schlachtfeld) ausführen. Tue ich das schon mit mache ich das schon mit
require('./routes/battlefield')(io)
?
bin/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;
Ich habe versucht, meine Routen in io.on('connection', function (socket) {
Einwickeln der Lage sein, socket
zu verwenden und statt 'Socket ist nicht definiert', das Ereignis tritt nicht auf.
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;
};
Ich entschuldige mich für so eine lange Frage. DANKE für jede Hilfe!
EDIT1: diese Frage Schreiben aus mir geholfen, das Problem besser zu verstehen. Ich habe server.listen(port);
in meinem bin/www auskommentiert und nodemon funktioniert jetzt. Allerdings stürzt die App auf Heroku ab. Mein Procfile ist web: node ./bin/www
... muss das geändert werden?
EDIT2: Nach herauszufinden Edit1 und ein bisschen googeln, fand ich, dass ich nicht server.listen();
(bin/www) undhttp.listen(3000);
(app.js) haben kann.
In bin/www, entfernte ich server.listen();
.
In app.js, habe ich aus Gründen der Übersichtlichkeit var http = ... zu var server = ... geändert und habe für process.env.PORT || '3000';
, aus bin/www. Ich habe auch app.set('socketio', io);
entfernt, weil es so aussieht, als würde es nichts tun ... Ich frage mich, warum es da drin war.
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);
Dies macht auch Heroku Arbeit wegen process.env.PORT
, hurra! Ich denke, node app.js
funktioniert, weil ich die App mit app.js initialisiert habe, ich denke, bin/www wird nicht ausgeführt, wenn Sie das tun?
Ich brauche immer noch Hilfe mit # 1 (mit socket.broadcast.emit).
EDIT 3: Nun, es dauerte buchstäblich den ganzen Tag, aber ich glaube, ich habe es mit einer Eigenart herausgefunden. Natürlich konnte ich socket
nicht verwenden, es ist ein Parameter, der beim Verbinden gegeben wird. Ich muss auch über verschiedene Routen Socket zugreifen und gefunden this SO question. Dies ist, was ich am Ende in battlefield.js tun:
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;
(Anmerkung: Ich habe eine Menge meiner eigenen Code aus, damit ich weiß nicht, ob diese Kopie und pasteable bereit ist, und Sie sollten wahrscheinlich überprüfen dieser Sockel ist nicht null)
Ohne setTimeout
ist Sockel auf GET '/' nicht definiert. Zu meinem Verständnis muss die Seite zuerst rendern ... Seltsam, dass 200 manchmal nicht für mich funktioniert und 500 tut es. Ich kann es bei 500 lassen, aber das ist für ein Spiel, also ist die Zeit ziemlich wichtig.
Meine Fragen sind jetzt:
diese verbessert werden kann/ist es eine Möglichkeit, dies ohne SetTimeout tun kann? Sehe ich Clients mit diesem Code richtig an und bin ich (Frage # 4 da oben ^) effizient mit Socket.IO?
P.S. Wenn niemand diese Fragen beantwortet, werde ich dies bearbeiten, die Frage beantworten und meine Antwort als beste Antwort akzeptieren.