IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

NodeJS Discussion :

socket.on fait baisser framerate


Sujet :

NodeJS

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Points : 105
    Points
    105
    Par défaut socket.on fait baisser framerate
    Bonjour,

    Ma boucle de jeu côté client attend un event "message" envoyé par le serveur. Je n'ai pas mis le détail ici, mais cette fonction reçoit des données pour générer et dessiner des canvas, en gros. Fonction assez gourmande donc, on peut optimiser au maximum mais dessiner, ça commence des ressources.

    Ma problématique est que lorsque le client reçoit ces messages, le framerate baisse drastiquement, puisque le traitement de cette fonction est long. Mais je suis surpris, parce que socket.on est sensé être asynchrone ? A voir la chute de FPS à chaque réception de message, j'ai vraiment l'impression que socket.on bloque requestAnimationFrame. Voici un code simplifié :

    server.js
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    const app = require('express')();
    const http = require('http').Server(app);
    const io = require('socket.io')(http);
     
    app.get('/', (req, res) => // fol
    {
        res.sendFile('/var/www/html/Alborz/public/test.html');
    });
     
    // server intiialization 
    http.listen(5000, () => 
    { 
        console.log('started.');
     
        io.on('connection', (socket) => // fol
        {
            console.log('jey!');
     
            socket.on('sendMeMessage', function() // fol
            {
                socket.emit('message', {});
            });
     
        });
    })
    index.js
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
     
            <link rel="stylesheet" href="https://cdn.webix.com/edge/webix.css" type="text/css">
            <script src="https://cdn.webix.com/edge/webix.js" type="text/javascript"></script>
     
        </head>
     
        <body>
     
            <script src="/socket.io/socket.io.js"></script> 
     
            <script>
                
                let world = // fold
                { 
                    _socket:undefined,
                    _frames : 0,
                    _now : undefined,
                    _before : new Date(),
     
                    update:function() {
                        
                        // do some things
                        
                        world._now = new Date();
                        
                        if (world._now - world._before > 1000) {
                            $$("framerate").define("value", world._frames);
                            $$("framerate").refresh();
                            world._before = world._now;
                            world._frames = 0;
                        } else {
                            world._frames++;
                        }
                        
                    },
     
                    loop:function() {
                        
                        world.update();
                        
                        requestAnimationFrame(world.loop);
                    },
                };
                
                webix.ready(function() {
                    
                    world._socket = io();
                    
                    // windows avec text en haut à droite
                    webix.ui( // fold
                    {
                        view:"window",
                        head:false,
                        autofit:true,
                        zIndex:2000,
                        body:{
                            id:'framerate',
                            view:"text", 
                            value:"", 
                            readonly:true,
                            labelWidth:0,  
                            width:100,
                            tooltip:'FPS',
                        },
                        css:{
                            'background-color': 'transparent !important',
                            'box-shadow': 'none !important'
                        },
                        borderless:true,
                        
                    }).show({ x:window.innerWidth-108, y:7 });
            
                    world.loop();
                    
                        // ok
                        world._socket.on('message', function() // fol
                        {
                            for (let i=0; i<1000000000; i++) {
                                let a = i * 5;
                                a = a % 3;
                            }
                            console.log('done');
                        });
                        
                    document.addEventListener("keydown", function() {
                        world._socket.emit('sendMeMessage', {});
                    }, false);
     
                });
     
            </script>
        </body>
    </html>
    "There should be no boundaries to human endeavor" - Hawking
    Retrouvez moi sur GitHub : https://github.com/JeanLouisMassei

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 112
    Points
    44 112
    Par défaut
    Bonjour,
    Ma problématique est que lorsque le client reçoit ces messages, le framerate baisse drastiquement, puisque le traitement de cette fonction est long. Mais je suis surpris, parce que socket.on est sensé être asynchrone ? A voir la chute de FPS à chaque réception de message, j'ai vraiment l'impression que socket.on bloque
    oui mais dans le navigateur ton script est synchrone, tu entres dans la boucle et tu en ressors, entre temps la fonction liée à requestAnimationFrame est mise en attente, le moteur de rendu n'est pas prioritaire.
    Fais un affichage direct de world._frames++ dans ta fonction et tu verras que affichage se fige le temps de l’exécution de la boucle aussi longue/courte soit-elle.

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Points : 105
    Points
    105
    Par défaut
    Salut,

    Trouvé !

    En déléguant la fonction gourmande à un Web Worker, et grâce à la magnifique fonction transferControlToOffscreen (qui permet donc de draw sur un canvas de DOM dans un thread séparé), tout est rentré dans l'ordre C'est quand même power, le web...

    Bonne journée !!
    "There should be no boundaries to human endeavor" - Hawking
    Retrouvez moi sur GitHub : https://github.com/JeanLouisMassei

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 09/05/2010, 00h36
  2. Réponses: 0
    Dernier message: 09/07/2009, 13h39
  3. Réponses: 0
    Dernier message: 09/07/2009, 13h39
  4. Div qui fait baisser une autre div
    Par kate59 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 25/01/2009, 21h10
  5. Problème socket : le write ne se fait qu'au moment du close
    Par Synn dans le forum Développement
    Réponses: 6
    Dernier message: 23/05/2006, 15h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo