Simple Way to Implement Server Sent Events in Node.js?

前端 未结 6 1291
南方客
南方客 2021-01-31 06:11

I\'ve looked around and it seems as if all the ways to implement SSEs in Node.js are through more complex code, but it seems like there should be an easier way to send and recei

相关标签:
6条回答
  • 2021-01-31 06:35

    Here is an express server that sends one Server-Sent Event (SSE) per second, counting down from 10 to 0:

    const express = require('express')
    
    const app = express()
    app.use(express.static('public'))
    
    app.get('/countdown', function(req, res) {
      res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
      })
      countdown(res, 10)
    })
    
    function countdown(res, count) {
      res.write("data: " + count + "\n\n")
      if (count)
        setTimeout(() => countdown(res, count-1), 1000)
      else
        res.end()
    }
    
    app.listen(3000, () => console.log('SSE app listening on port 3000!'))
    

    Put the above code into a file (index.js) and run it: node index

    Next, put the following HTML into a file (public/index.html):

    <html>
    <head>
      <script>
      if (!!window.EventSource) {
        var source = new EventSource('/countdown')
    
        source.addEventListener('message', function(e) {
          document.getElementById('data').innerHTML = e.data
        }, false)
    
        source.addEventListener('open', function(e) {
          document.getElementById('state').innerHTML = "Connected"
        }, false)
    
        source.addEventListener('error', function(e) {
          const id_state = document.getElementById('state')
          if (e.eventPhase == EventSource.CLOSED)
            source.close()
          if (e.target.readyState == EventSource.CLOSED) {
            id_state.innerHTML = "Disconnected"
          }
          else if (e.target.readyState == EventSource.CONNECTING) {
            id_state.innerHTML = "Connecting..."
          }
        }, false)
      } else {
        console.log("Your browser doesn't support SSE")
      }
      </script>
    </head>
    <body>
      <h1>SSE: <span id="state"></span></h1>
      <h3>Data: <span id="data"></span></h3>
    </body>
    </html>
    

    In your browser, open localhost:3000 and watch the SSE countdown.

    0 讨论(0)
  • 2021-01-31 06:40
    **client.js**
    
    var eventSource = new EventSource("/route/events");
    eventSource.addEventListner("ping", function(e){log(e.data)});
    
    //if no events specified
    eventSource.addEventListner("message", function(e){log(e.data)});
    
    **server.js**
    
    http.createServer((req, res)=>{
    
        if(req.url.indexOf("/route/events")>=){
    
          res.setHeader('Connection', 'keep-alive');
    
          res.setHeader("Cache-Control", "no-cache");
    
          res.setHeader("Content-Type", "text/event-stream");
    
          let event = "event: ping";
    
          let id = `id: ${Date.now()}`;
    
          let data = {
             message:`hello @${new Date().toString()}`
          }
    
          data = "data: "+JSON.stringify(data);
    
          res.end(`${event}\n${id}\n${data}\n\n`);
       }
    }).listen(PORT)
    
    0 讨论(0)
  • 2021-01-31 06:42

    You should be able to do such a thing using Socket.io. First, you will need to install it with npm install socket.io. From there, in your code you will want to have var io = require(socket.io);

    You can see more in-depth examples given by Socket.IO

    You could use something like this on the server:

    var express = require('express');
    var app = express();
    var server = require('http').createServer(app);
    var io = require('../..')(server);
    var port = process.env.PORT || 3000;
    
    server.listen(port, function () {
      console.log('Server listening at port ' + port);
    });
    
    app.use(express.static(__dirname + '/public'));
    
    io.on('connection', function (socket) {
        socket.emit('EVENT_NAME', {data});
    });
    

    And something like this on the client:

    <script src="socket_src_file_path_here"></script>
    <script>
      var socket = io('http://localhost');
      socket.on('EVENT_NAME', function (data) {
        console.log(data);
        //Do whatever you want with the data on the client
      });
    </script>
    
    0 讨论(0)
  • 2021-01-31 06:44

    If you're using express this is the easiest way https://www.npmjs.com/package/express-sse

    on BE:

    const SSE = require('express-sse');
    
    const sse = new SSE();
    
    ...
    
    app.get('/sse', sse.init);
    
    ...
    
    sse.send('message', 'event-name');
    

    on FE:

    const EventSource = require('eventsource');
    
    const es = new EventSource('http://localhost:3000/sse');
    
    es.addEventListener('event-name', function (message) {
      console.log('message:', message)
    });
    
    0 讨论(0)
  • 2021-01-31 06:45

    I'm adding a simple implementation of SSE here. It's just one Node.js file.

    You can have a look at the result here: https://glossy-ox.glitch.me/

    const http = require('http');
    const port = process.env.PORT || 3000;
    
    const server = http.createServer((req, res) => {
      // Server-sent events endpoint
      if (req.url === '/events') {
        res.writeHead(200, {
          'Content-Type': 'text/event-stream',
          'Cache-Control': 'no-cache',
          'Connection': 'keep-alive',
        });
    
        const refreshRate = 1000; // in milliseconds
        return setInterval(() => {
          const id = Date.now();
          const data = `Hello World ${id}`;
          const message =
            `retry: ${refreshRate}\nid:${id}\ndata: ${data}\n\n`;
          res.write(message);
        }, refreshRate);
      }
    
      // Client side
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.end(`
        <!DOCTYPE html>
        <html lang="en" dir="ltr">
          <head>
            <meta charset="utf-8">
            <title>SSE</title>
          </head>
          <body>
            <pre id="log"></pre>
          </body>
          <script>
            var eventSource = new EventSource('/events');
            eventSource.onmessage = function(event) {
              document.getElementById('log').innerHTML += event.data + '<br>';
            };
          </script>
        </html>
      `);
    });
    
    server.listen(port);
    
    server.on('error', (err) => {
      console.log(err);
      process.exit(1);
    });
    
    server.on('listening', () => {
      console.log(`Listening on port ${port}`);
    });
    
    0 讨论(0)
  • 2021-01-31 06:47

    I found SSE implementation in node.js.

    Github link: https://github.com/einaros/sse.js

    NPM module:https://www.npmjs.com/package/sse

    Will above link helps you ?

    0 讨论(0)
提交回复
热议问题