所以在服务器中我试图将一些属性绑定到我可以从客户端读取的套接字对象,但这只适用于第一个属性。
继续我的运行
socket.isPlayer = true;
socket.isWaiting = true;
socket.playerNum = 0;
但在客户端上,我看到的是socket.isPlayer
属性。任何想法都在继续,非常感谢。
这是我的完整服务器端文件
'use strict';
var mongoose = require('mongoose'),
PlayingGame = mongoose.model('PlayingGame'),
FinishedGame = mongoose.model('FinishedGame');
var waitingGame = null;
/*we use this variable to refrence the socket of the waiting player
so when we start a game we can set the isWaiting attribute to false
prevent joining a game with yourself*/
var waitingSocket = null;
/* HELPERS */
var emitError = function(socket, err) {
socket.emit(err);
};
var getSocketGameId = function(socket) {
for (var room in socket.rooms) {
if (room.substring(0, 4) === 'game') {
return room.substring(5);
}
}
return null;
}
/* helpers */
var createNewGame = function(socket, username) {
var newGame = {};
newGame.player1 = username;
var playingGame = new PlayingGame(newGame);
socket.join('game:' + playingGame.id);
waitingGame = playingGame;
console.log('new game room id', waitingGame.id);
socket.isPlayer = true;
socket.isWaiting = true;
socket.playerNum = 0;
console.log('socket', socket.playerNum);
waitingSocket = socket;
};
var startNewGame = function(socket, username, io) {
socket.isPlayer = true;
socket.playerNum = 1;
console.log('starting new game');
waitingGame.player2 = username;
waitingGame.save(function(err) {
if (err) emitError('Failed to save game');
else {
socket.join('game:' + waitingGame.id);
io.to('game:' + waitingGame.id).emit('start new game', waitingGame);
}
waitingGame = null;
waitingSocket.isWaiting = false;
waitingSocket = null;
});
};
var closeGame = function(socket, io) {
console.log('closing game');
// Check if game is still playing if no, assume its already been closed, do nothing
var gameId = getSocketGameId(socket);
if (gameId === null) return;
console.log('finding ', gameId);
PlayingGame.findById(gameId, function(err, game) {
if (err) {
console.log(err);
throw 'Problem finding game when closing';
}
console.log(game);
// if game found, move PlayingGame to FinishedGame emit game closed to room
if (game) {
console.log('Saving game to finished games');
var finishedGame = new FinishedGame(game.toObject());
finishedGame.save(function(err) {
if (err) throw 'Problem saving finished game when moving playing game to finished game';
console.log('Successfuly saved to finish game');
game.remove(function(err) {
if (err) throw 'Problem removing from playing games';
socket.leave('game:' + gameId);
// send message to room that the game has been closed
io.to('game:' + gameId).emit('game closed');
});
});
}
});
};
var startSpectating = function(socket, gameId) {
// Send game info
var gameInfo;
var found = false;
PlayingGame.findById(gameId, function(err, game) {
if (err) socket.emit('game not found');
else {
gameInfo = game;
socket.emit('gameInfo')
// Join game room
socket.join('game:' + gameId);
socket.isPlayer = false;
}
});
};
module.exports = function(io, socket) {
socket.on('join game', function(data) {
console.log('New game request', data);
if (waitingGame == null) createNewGame(socket, data.username);
else startNewGame(socket, data.username, io);
});
socket.on('disconnect', function() {
console.log('socket disconnected');
if (socket.isPlayer) closeGame(socket, io);
});
socket.on('leaving game', function() {
console.log('leaving game');
if (socket.isPlayer) {
if (socket.isWaiting) {
waitingGame = null;
waitingSocket = null;
} else {
closeGame(socket, io);
}
} else {
// the socket is a spectator all we need to do is remove from room
for (var room in socket.rooms) {
if (room.substring(0, 4) === 'game') {
socket.leave(room);
}
}
}
});
socket.on('spectate', function(data) {
startSpectating(socket, data.gameId);
});
};
答案 0 :(得分:0)
简短的回答是“你不能这样做”。下面很长一点。
socket
是应用程序服务器端的对象。目前我不知道在服务器和客户端之间共享属性的自动方式。这样做的原因是它是一个简单的套接字连接,所有应该共享的数据必须以某种方式旅行到客户端。因此,简单地设置属性意味着将实际的包发送给客户端。
但这非常低效,因为这意味着您无法存储服务器端的任何类型的属性,而不会将它们发送到客户端。大多数时候你确实需要这样一个“选项”。
此外,简单地设置属性在纯JavaScript中什么都不做 - 你必须拥有所谓的魔术函数,getter / setter,以及任何类型的“新”类型的JS功能。我的意思是没有内置的方法来确定你是否设置了什么,这是你情况下的第二个大禁忌。
P.S。
如果您仔细阅读了您分享的主题,则只需说明Note that this is only on one side (either client or server)
。它只是一种设置属性的方法,以确保您不会覆盖任何方法(例如emit
)。