12
votes

Socket.io: Comment limiter la taille des données émises du client sur le serveur WebSocket

J'ai un serveur nœud.js avec socket.io. Mes clients utilisent Socket.io pour se connecter au serveur Node.js.

Les données sont transmises des clients au serveur de la manière suivante:

sur le client xxx

sur le serveur xxx

supposons que quelqu'un modifie son client et émet au serveur un très gros morceau de données. Par exemple: xxx

à cause de cette boucle sur le serveur ... xxx

... Le serveur prendrait Un très long moment de boucler à travers toutes ces données.

Donc, quelle est la meilleure solution pour empêcher de tels scénarios?

Merci

EDIT:

J'ai utilisé cette fonction pour valider l'objet: xxx


2 commentaires

Vous pouvez réécrire les fonctions EMIT () et Broadcast () pour arrêter les données importantes d'être envoyées. Quelqu'un peut toujours pirater votre code client afin que vous souhaitiez également utiliser une validation côté serveur.


Si la taille compte des octets plutôt que dans les clés, vous ne pouvez pas simplement le régler et vérifier la longueur?


5 Réponses :


1
votes

Peut-être détruire la taille du tampon est ce dont vous avez besoin.

du wiki :

  • Détruisez la taille de la mémoire tampon par défaut sur 10e7

    utilisé par les transports HTTP. Les corps de requête HTTP tampons Socket.io Server jusqu'à cette limite. Cette limite n'est pas appliquée à Websket ou Flashsockets.


1 commentaires

Vous avez dit que la limite n'est pas appliquée aux webockets. Mais c'est exactement ce dont j'ai besoin. J'ai besoin d'une limite pour les données envoyées à travers WebSockets.



2
votes

Eh bien, je vais aller avec le côté JavaScript de la chose ... Disons que vous ne vouliez pas permettre aux utilisateurs de passer sur une certaine limite de données, vous pouvez simplement:

var allowedSize = 10;

Object.keys(Data).map(function( key, idx ) {
    if( idx > allowedSize ) return;
    // Do some work with Data[key]
});


2 commentaires

C'est bien pour la validation du côté serveur. Mais je veux empêcher que de gros morceaux de données soient automatiquement rejetés afin qu'ils ne soient même pas disponibles à l'intérieur du code côté serveur. Et si quelqu'un envoie un objet vraiment gros qui consomme toute la mémoire du serveur? Est-ce une préoccupation que je devrais prendre en compte lors de la rédaction d'applications qui utilisent des webockets ou devrais-je simplement effectuer une validation du côté serveur en code et c'est tout?


@ user3179196 Vous voudrez peut-être vérifier la réponse acceptée ici Stackoverflow.com/questions/13010354/ ... ;)



4
votes

La chose la plus facile à faire est de vérifier la taille des données avant de faire quoi que ce soit avec elle. XXX

Pour être honnête, c'est un peu inefficace. Votre client envoie le message, Socket.io analyse le message dans un objet, puis vous obtenez l'événement et le retourne dans une chaîne.

Si vous souhaitez être encore plus efficace, alors sur le côté du client. Vous devriez exécuter des longueurs maximales de messages.

Pour encore plus d'efficacité (et de protéger contre les utilisateurs malveillants), car les paquets entrent dans Socket.io, si la longueur devient trop longue, alors vous devez les supprimer. Vous devrez soit comprendre un moyen d'étendre les prototypes pour faire ce que vous voulez, soit vous devrez tirer la source et la modifier vous-même. De plus, je n'ai pas regardé le protocole Socket.io, mais je suis sûr que vous devrez faire plus que simplement "jeter" le paquet. En outre, certains paquets sont des dossiers ACK et des nack-dos afin que vous ne voulez pas gâcher avec ceux-ci, non plus.


Note latérale: Si vous ne vous souciez que du nombre de clés, alors vous pouvez. Utilisez objet.keys (obj) qui renvoie un tableau de clés: xxx


0 commentaires

3
votes

Vous pouvez probablement envisager de passer à Socket.io-Stream et gérer l'entrée Stream directement.

De cette façon, vous devez rejoindre les morceaux et enfin analyser l'entrée JSON manuellement, mais vous avez la chance de fermer la connexion lorsque la longueur de données d'entrée dépasse le seuil que vous décidez.

sinon sinon (séjour avec socket.io approche ) Votre rappel ne sera pas appelé tant que le flux de données total a été reçu. Cela n'arrête pas votre exécution du fil principal JS, mais décheter la mémoire, la CPU et la bande passante.

D'autre part, si votre seul objectif est d'éviter la surcharge de votre algorithme de traitement, vous pouvez continuer à la limiter en comptant éléments de l'objet reçu. Par exemple: xxx


0 commentaires

3
votes

edit : parce que la question concerne "Comment gérer la surcharge de serveur", vous devez vérifier l'équilibrage de la charge avec gninx http://nginx.com/blog/nginx-nodejs-websockets-socketso/ - Vous pouvez avoir des serveurs supplémentaires au cas où un client crée un goulot d'étranglement. Les autres serveurs seraient disponibles. Même si vous résolvez ce problème, il y a toujours d'autres problèmes, comme le client envoiant plusieurs petits paquets et ainsi de suite.

La socket.io -Library semble être un peu problématique, la gestion de messages trop gros n'est pas disponible sur la couche WebSockets, il y a trois ans il y a trois ans, ce qui donne une idée de la manière dont il pourrait être résolu:

https://github.com/automattique/socket.io/issues/886 < / a>

Toutefois, car WebSockets -Protocol a une taille de paquets finis, il vous permettrait d'arrêter le traitement des paquets si une certaine taille a été réalisée. Le moyen le plus efficace de ce faire serait avant que le paquet soit stransformé vers le tas JavaScript. Cela signifie que vous devez gérer la transformation Websocket manuellement - c'est ce que le socket.io fait pour vous, mais cela ne prend pas en compte la taille du paquet.

Si vous souhaitez implémenter votre propre couche Websocket, l'utilisation de cette implémentation de la norme WebSocket peut être utile:

https://github.com/theturtle32/websocket-node

Si vous n'avez pas besoin de prendre en charge les navigateurs plus âgés, à l'aide de cette section pure WebSockets -Accoch pourrait être une solution appropriée.


1 commentaires

Malheureusement, vous perdez des choses comme des sessions reconnectes et la reconnexion automatique du client, quelle socket.io fournit.