Search code examples
javascriptjqueryxmlserver-sent-events

Reading an XML file using Jquery, how to combine this with Server Sent Events and keep the page up-to-date?


I have the following XML file (data.xml):

<?xml version="1.0" encoding="UTF-8"?>
<users>
  <user>
      <id>2011</id>
      <posX>12</posX>
      <posY>29</posY>
      <title>Senior Developer</title>
  </user>
  <user>
      <id>2022</id>
      <posX>99</posX>
      <posY>99</posY>
      <title>updated!</title>
  </user>
</users>

I read this file using jquery:

$.ajax({
                    url: 'js/data.xml', // name of file you want to parse
                    dataType: "xml",
                    success: parse,
                    error: function(){alert("Error: Something went wrong");}
                  });

and display it using;

function parse(document){
                  $(document).find("user").each(function(){ 
                    $("#test").append(  // this is where all the reading and writing will happen
                    '<div style="position: absolute; top: '+$(this).find('posY').text()+'px; left: '+$(this).find('posX').text()+'px; width: 100px; height: 100px;">ID: '+$(this).find('id').text()+ // which represents user->id
                    '<br /> X: '+$(this).find('posX').text()+
                    '<br /> Y: '+$(this).find('posY').text()+
                    '<br /> Title: '+$(this).find('title').text()+
                    '</div>'
                    );
                  });
                }

This all works fine. The XML is read and the data is displayed. Now this only happens when you load the page, so 1 time only.

It is possible for users to update the xml (let's say the title is changed), but you only see these changes if you refresh the page. I know you can load the the xmlfile each x seconds using jquery, but I've also read that server send events can push the xml file when changes are made in it.

I would like to do just that. The problem is: how do I implement SSE to achieve this?

I did some research and found some demo code:

var source = new EventSource("js/data.xml");
source.onmessage = function(event) {
    document.getElementById("test").innerHTML += event.data + "<br>";
};

but this didn't work.

So what I want:

  1. Load page + load XML (this is what is currently does)
  2. if the XML is changed in anyway, push the xml to the page (using SSE)
  3. display the data (so if posX is changed, the div should be moved aswell)

My current working HTML code minus the SSE:

<!DOCTYPE html>
<html lang="en">
    <head>
      <style>
       #test { position: relative; width: 500px; height: 500px; padding: 0.5em; border: 1px solid red;}
        </style>
    </head>
    <body>
        <div id="test"></div>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js "></script>
        <script type="text/javascript">
            $(document).ready(function(){

                function parse(document){
                  $(document).find("user").each(function(){ 
                    $("#test").append(  // this is where all the reading and writing will happen
                    '<div style="position: absolute; top: '+$(this).find('posY').text()+'px; left: '+$(this).find('posX').text()+'px; width: 100px; height: 100px;">ID: '+$(this).find('id').text()+ // which represents user->id
                    '<br /> X: '+$(this).find('posX').text()+
                    '<br /> Y: '+$(this).find('posY').text()+
                    '<br /> Title: '+$(this).find('title').text()+
                    '</div>'
                    );
                  });
                }

                  $.ajax({
                    url: 'js/data.xml', // name of file you want to parse
                    dataType: "xml",
                    success: parse,
                    error: function(){alert("Error: Something went wrong");}
                  });
            });
        </script>
    </body>
</html>

Hope someone can help me out


Solution

  • From my comment:

    As far as I can tell you cannot do this with a static file. The server must send specific data to the client to trigger the event. see: developer.mozilla.org/en-US/docs/Server-sent_events/… My best advice whould be to set up a timeout and perform a HEAD request and check to see if the Last Modified date has changes on the XML file.

    Similar question:

    $.ajax() call, only on updation

    $.ajax({
      type: "GET",
      ifModified: true,
      url: 'js/data.xml',
      dataType: "xml",
      success: parse
    });
    

    This will only call success if the XML file has been updated since the last request.