Koa SSE connection reconnecting










0















I have set up an SSE connection using Koa like so:



const Koa = require('koa');
const Router = require('koa-router');

const app = new Koa();
const router = new Router();

// Sets up the HTTP header and sends a message via SSE
function writeSSE(ctx, message)
ctx.res.writeHead(200,
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'Access-Control-Allow-Origin': '*',
);

ctx.res.write(`id: 01n`);
ctx.res.write(`data: $messagenn`);


// Router Middleware
router.get('/stream', (ctx, next) =>
writeSSE(ctx, 'Stream reached.');
);

app.use(router.routes()).use(router.allowedMethods());

app.listen(8080);


Where my React components starts the connection like so:



new EventSource("http://localhost:8080/stream")


The component then receives the answer sent by the writeSSE method on the backend.



But for some reason the /stream endpoint is reached every 3 seconds or so, as if the connection was being reestablished.



And my error listener on the front-end catches a CONNECTING event every time.



this.state.source.onerror = (e) => 
if (e.target.readyState == EventSource.CONNECTING)
console.log("Connecting...");

;


And on the back-end, ctx.response equals status: 404, message: 'Not Found', header: .



Would anyone know the cause of this issue? Is it linked to the way I use Koa?










share|improve this question


























    0















    I have set up an SSE connection using Koa like so:



    const Koa = require('koa');
    const Router = require('koa-router');

    const app = new Koa();
    const router = new Router();

    // Sets up the HTTP header and sends a message via SSE
    function writeSSE(ctx, message)
    ctx.res.writeHead(200,
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    Connection: 'keep-alive',
    'Access-Control-Allow-Origin': '*',
    );

    ctx.res.write(`id: 01n`);
    ctx.res.write(`data: $messagenn`);


    // Router Middleware
    router.get('/stream', (ctx, next) =>
    writeSSE(ctx, 'Stream reached.');
    );

    app.use(router.routes()).use(router.allowedMethods());

    app.listen(8080);


    Where my React components starts the connection like so:



    new EventSource("http://localhost:8080/stream")


    The component then receives the answer sent by the writeSSE method on the backend.



    But for some reason the /stream endpoint is reached every 3 seconds or so, as if the connection was being reestablished.



    And my error listener on the front-end catches a CONNECTING event every time.



    this.state.source.onerror = (e) => 
    if (e.target.readyState == EventSource.CONNECTING)
    console.log("Connecting...");

    ;


    And on the back-end, ctx.response equals status: 404, message: 'Not Found', header: .



    Would anyone know the cause of this issue? Is it linked to the way I use Koa?










    share|improve this question
























      0












      0








      0








      I have set up an SSE connection using Koa like so:



      const Koa = require('koa');
      const Router = require('koa-router');

      const app = new Koa();
      const router = new Router();

      // Sets up the HTTP header and sends a message via SSE
      function writeSSE(ctx, message)
      ctx.res.writeHead(200,
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive',
      'Access-Control-Allow-Origin': '*',
      );

      ctx.res.write(`id: 01n`);
      ctx.res.write(`data: $messagenn`);


      // Router Middleware
      router.get('/stream', (ctx, next) =>
      writeSSE(ctx, 'Stream reached.');
      );

      app.use(router.routes()).use(router.allowedMethods());

      app.listen(8080);


      Where my React components starts the connection like so:



      new EventSource("http://localhost:8080/stream")


      The component then receives the answer sent by the writeSSE method on the backend.



      But for some reason the /stream endpoint is reached every 3 seconds or so, as if the connection was being reestablished.



      And my error listener on the front-end catches a CONNECTING event every time.



      this.state.source.onerror = (e) => 
      if (e.target.readyState == EventSource.CONNECTING)
      console.log("Connecting...");

      ;


      And on the back-end, ctx.response equals status: 404, message: 'Not Found', header: .



      Would anyone know the cause of this issue? Is it linked to the way I use Koa?










      share|improve this question














      I have set up an SSE connection using Koa like so:



      const Koa = require('koa');
      const Router = require('koa-router');

      const app = new Koa();
      const router = new Router();

      // Sets up the HTTP header and sends a message via SSE
      function writeSSE(ctx, message)
      ctx.res.writeHead(200,
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive',
      'Access-Control-Allow-Origin': '*',
      );

      ctx.res.write(`id: 01n`);
      ctx.res.write(`data: $messagenn`);


      // Router Middleware
      router.get('/stream', (ctx, next) =>
      writeSSE(ctx, 'Stream reached.');
      );

      app.use(router.routes()).use(router.allowedMethods());

      app.listen(8080);


      Where my React components starts the connection like so:



      new EventSource("http://localhost:8080/stream")


      The component then receives the answer sent by the writeSSE method on the backend.



      But for some reason the /stream endpoint is reached every 3 seconds or so, as if the connection was being reestablished.



      And my error listener on the front-end catches a CONNECTING event every time.



      this.state.source.onerror = (e) => 
      if (e.target.readyState == EventSource.CONNECTING)
      console.log("Connecting...");

      ;


      And on the back-end, ctx.response equals status: 404, message: 'Not Found', header: .



      Would anyone know the cause of this issue? Is it linked to the way I use Koa?







      server-sent-events koa koa2






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 14 '18 at 8:21









      ChristopherChristopher

      682525




      682525






















          1 Answer
          1






          active

          oldest

          votes


















          0














          I'm in the process of implementing a Koa-based server for SSE. I've been running into the same problem, and here are my thoughts / working solution:



          As far as I can tell, the reason why onmessage and onerror keep getting called is because the EventSource object on the client side is emitting an error event. This is causing the connection to be disconnected, which causes the client to send another request to initialize the stream to the server. From here, the process repeats itself indefinitely.



          Based on my own testing, EventSource is emitting an error due to the data that is being sent back from the server. Per the docs, a 200 response that has as Content-Type other than 'text/event-stream' will cause a failure.



          In your example, you have declared your response as 'text/event-stream' and are passing a string into the ctx.res.write method. While this looks correct, and in fact works when using comparable code and Express, it seems that it doesn't work in Koa. However, if you change the 'data' you are writing to your response to a stream, such as this example here, you'll find that the connection establishes correctly.



          Maybe try the following:






          //require Passthrough
          const PassThrough = require('stream').PassThrough;

          //then, in your writeSSE function, try this:
          let stream = new PassThrough();
          stream.write(`data: $messagenn`);
          ctx.res.write(stream);





          I'm not 100% sure why this change works. My best guess is that there is something about Koa's ctx object that prevents a plain string or template literal from being viewed as valid text/event-stream data, but this is entirely supposition (this begs the question as to why it works in Express, but hopefully someone more knowledgeable can answer this for both of us). From what I've seen of other snippets published online, the stream approach is the one to take in Koa.



          I'm not sure what your results will be, as it looks like you may be using a different version of Koa than I am, but I'd give it a shot. I was able to get my connection established correctly making this small change.






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295738%2fkoa-sse-connection-reconnecting%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I'm in the process of implementing a Koa-based server for SSE. I've been running into the same problem, and here are my thoughts / working solution:



            As far as I can tell, the reason why onmessage and onerror keep getting called is because the EventSource object on the client side is emitting an error event. This is causing the connection to be disconnected, which causes the client to send another request to initialize the stream to the server. From here, the process repeats itself indefinitely.



            Based on my own testing, EventSource is emitting an error due to the data that is being sent back from the server. Per the docs, a 200 response that has as Content-Type other than 'text/event-stream' will cause a failure.



            In your example, you have declared your response as 'text/event-stream' and are passing a string into the ctx.res.write method. While this looks correct, and in fact works when using comparable code and Express, it seems that it doesn't work in Koa. However, if you change the 'data' you are writing to your response to a stream, such as this example here, you'll find that the connection establishes correctly.



            Maybe try the following:






            //require Passthrough
            const PassThrough = require('stream').PassThrough;

            //then, in your writeSSE function, try this:
            let stream = new PassThrough();
            stream.write(`data: $messagenn`);
            ctx.res.write(stream);





            I'm not 100% sure why this change works. My best guess is that there is something about Koa's ctx object that prevents a plain string or template literal from being viewed as valid text/event-stream data, but this is entirely supposition (this begs the question as to why it works in Express, but hopefully someone more knowledgeable can answer this for both of us). From what I've seen of other snippets published online, the stream approach is the one to take in Koa.



            I'm not sure what your results will be, as it looks like you may be using a different version of Koa than I am, but I'd give it a shot. I was able to get my connection established correctly making this small change.






            share|improve this answer



























              0














              I'm in the process of implementing a Koa-based server for SSE. I've been running into the same problem, and here are my thoughts / working solution:



              As far as I can tell, the reason why onmessage and onerror keep getting called is because the EventSource object on the client side is emitting an error event. This is causing the connection to be disconnected, which causes the client to send another request to initialize the stream to the server. From here, the process repeats itself indefinitely.



              Based on my own testing, EventSource is emitting an error due to the data that is being sent back from the server. Per the docs, a 200 response that has as Content-Type other than 'text/event-stream' will cause a failure.



              In your example, you have declared your response as 'text/event-stream' and are passing a string into the ctx.res.write method. While this looks correct, and in fact works when using comparable code and Express, it seems that it doesn't work in Koa. However, if you change the 'data' you are writing to your response to a stream, such as this example here, you'll find that the connection establishes correctly.



              Maybe try the following:






              //require Passthrough
              const PassThrough = require('stream').PassThrough;

              //then, in your writeSSE function, try this:
              let stream = new PassThrough();
              stream.write(`data: $messagenn`);
              ctx.res.write(stream);





              I'm not 100% sure why this change works. My best guess is that there is something about Koa's ctx object that prevents a plain string or template literal from being viewed as valid text/event-stream data, but this is entirely supposition (this begs the question as to why it works in Express, but hopefully someone more knowledgeable can answer this for both of us). From what I've seen of other snippets published online, the stream approach is the one to take in Koa.



              I'm not sure what your results will be, as it looks like you may be using a different version of Koa than I am, but I'd give it a shot. I was able to get my connection established correctly making this small change.






              share|improve this answer

























                0












                0








                0







                I'm in the process of implementing a Koa-based server for SSE. I've been running into the same problem, and here are my thoughts / working solution:



                As far as I can tell, the reason why onmessage and onerror keep getting called is because the EventSource object on the client side is emitting an error event. This is causing the connection to be disconnected, which causes the client to send another request to initialize the stream to the server. From here, the process repeats itself indefinitely.



                Based on my own testing, EventSource is emitting an error due to the data that is being sent back from the server. Per the docs, a 200 response that has as Content-Type other than 'text/event-stream' will cause a failure.



                In your example, you have declared your response as 'text/event-stream' and are passing a string into the ctx.res.write method. While this looks correct, and in fact works when using comparable code and Express, it seems that it doesn't work in Koa. However, if you change the 'data' you are writing to your response to a stream, such as this example here, you'll find that the connection establishes correctly.



                Maybe try the following:






                //require Passthrough
                const PassThrough = require('stream').PassThrough;

                //then, in your writeSSE function, try this:
                let stream = new PassThrough();
                stream.write(`data: $messagenn`);
                ctx.res.write(stream);





                I'm not 100% sure why this change works. My best guess is that there is something about Koa's ctx object that prevents a plain string or template literal from being viewed as valid text/event-stream data, but this is entirely supposition (this begs the question as to why it works in Express, but hopefully someone more knowledgeable can answer this for both of us). From what I've seen of other snippets published online, the stream approach is the one to take in Koa.



                I'm not sure what your results will be, as it looks like you may be using a different version of Koa than I am, but I'd give it a shot. I was able to get my connection established correctly making this small change.






                share|improve this answer













                I'm in the process of implementing a Koa-based server for SSE. I've been running into the same problem, and here are my thoughts / working solution:



                As far as I can tell, the reason why onmessage and onerror keep getting called is because the EventSource object on the client side is emitting an error event. This is causing the connection to be disconnected, which causes the client to send another request to initialize the stream to the server. From here, the process repeats itself indefinitely.



                Based on my own testing, EventSource is emitting an error due to the data that is being sent back from the server. Per the docs, a 200 response that has as Content-Type other than 'text/event-stream' will cause a failure.



                In your example, you have declared your response as 'text/event-stream' and are passing a string into the ctx.res.write method. While this looks correct, and in fact works when using comparable code and Express, it seems that it doesn't work in Koa. However, if you change the 'data' you are writing to your response to a stream, such as this example here, you'll find that the connection establishes correctly.



                Maybe try the following:






                //require Passthrough
                const PassThrough = require('stream').PassThrough;

                //then, in your writeSSE function, try this:
                let stream = new PassThrough();
                stream.write(`data: $messagenn`);
                ctx.res.write(stream);





                I'm not 100% sure why this change works. My best guess is that there is something about Koa's ctx object that prevents a plain string or template literal from being viewed as valid text/event-stream data, but this is entirely supposition (this begs the question as to why it works in Express, but hopefully someone more knowledgeable can answer this for both of us). From what I've seen of other snippets published online, the stream approach is the one to take in Koa.



                I'm not sure what your results will be, as it looks like you may be using a different version of Koa than I am, but I'd give it a shot. I was able to get my connection established correctly making this small change.






                //require Passthrough
                const PassThrough = require('stream').PassThrough;

                //then, in your writeSSE function, try this:
                let stream = new PassThrough();
                stream.write(`data: $messagenn`);
                ctx.res.write(stream);





                //require Passthrough
                const PassThrough = require('stream').PassThrough;

                //then, in your writeSSE function, try this:
                let stream = new PassThrough();
                stream.write(`data: $messagenn`);
                ctx.res.write(stream);






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Dec 29 '18 at 1:40









                Kyle HutchinsonKyle Hutchinson

                1




                1





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295738%2fkoa-sse-connection-reconnecting%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Barbados

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3