{"id":3783,"date":"2013-03-06T11:36:49","date_gmt":"2013-03-06T11:36:49","guid":{"rendered":"http:\/\/www.codekites.com\/?p=3783"},"modified":"2023-05-01T19:49:39","modified_gmt":"2023-05-01T14:19:39","slug":"monitor-progress-long-running-php-scripts-html5-server-sent-events","status":"publish","type":"post","link":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/","title":{"rendered":"Monitor progress of long running Php scripts with Html5 server sent events"},"content":{"rendered":"<h3>Server sent events<\/h3>\n<p>When running a long serverside task inside a web application it becomes very useful, if not necessary to report the progress of that task in realtime to the clientside, that is the browser. Earlier there was no easy way to do this and hacks had to be constructed to achieve such a realtime notification. Classical solutions include ajax polling, or even flash. But html5 brings new features to make this easier. And one such feature is server \"Server-send Events\".<\/p>\t\t<div class=\"display-ad-unit mobile-wide bsa\" style=\"background:#fff3f3; height:315px;\">\n\n<!-- BinaryTides_S2S_InContent_ROS_Pos1 -->\n<style>\n\t@media only screen and (min-width: 0px) and (min-height: 0px) {\n\t\tdiv[id^=\"bsa-zone_1611170977806-3_123456\"] {\n\t\t\tmin-width: 300px;\n\t\t\tmin-height: 250px;\n\t\t}\n\t}\n\t@media only screen and (min-width: 640px) and (min-height: 480px) {\n\t\tdiv[id^=\"bsa-zone_1611170977806-3_123456\"] {\n\t\t\tmin-width: 300px;\n\t\t\tmin-height: 250px;\n\t\t}\n\t}\n<\/style>\n<div id=\"bsa-zone_1611170977806-3_123456\"><\/div>\n\n\n<\/div>\n<!-- Time: 2.0027160644531E-5, Pos: 499, Key: ad_unit_1 -->\n\n\n<p>The \"Server side events\" api allows javascript to generate notifications of events on receiving data from the server. This means that the same connection persists, until it is finished and as the server sends messages, dom events are generated inside the browser so that the browser can handle them. With ajax, the browser cannot do anything till the whole transfer\/request finishes. That's the only and the main difference between ajax and server sent events.<\/p>\n<p>At this point you might be wondering about web sockets, a much more spoken about feature of html5 that is capable of bi-directional communication between server and browser. We shall talk about it bit later we shall look into the pros and cons of web sockets vs server sent events.<\/p>\n<h3>Quick Demo<\/h3>\n<p>Before going into the code, lets first take a look at what exactly are we trying to do. Click on the Start button and it will start a serverside script.<\/p>\n<p>Cool, isn't it. Now that we are done with the demo, its time to understand the technicals.<\/p>\n<h3>Code<\/h3>\n<h4>Client Side<\/h4>\n<p>On the client side, create an <strong>EventSource<\/strong> object and assign relevant event handlers. A very simple example looks like this<\/p>\n<pre class=\"source-code\" >if (!!window.EventSource) \r\n{\r\n\tvar source = new EventSource(&#039;task.php&#039;);\r\n\t\r\n\tsource.addEventListener(&#039;message&#039;, function(e) \r\n\t{\r\n\t\tconsole.log(e.data);\r\n\t\t\/\/Do whatever with e.data\r\n\t}, false);\r\n}<\/pre>\n<p>Note that the EventSource constructor is given the name of the php script to call, which is task.php over here. Now when task.php sends out data using echo for example, the message event shall be triggered which will receive an object containing the message from server. The server has to send messages like this<\/p>\n<pre class=\"source-code\" >echo &quot;data: The current status is that we have finished half the worknn&quot;;<\/pre>\n<p>Thats the protocol. The part after the 'data: '  is interpreted as the message. Every line in the message should have a newline at the end. And when there are 2 newlines, it indicates that one message is complete. It does not mean the end of the whole communication. The server can send another message and keep on doing that. The connection is kept alive as long as the server or client do not decide to close it.<\/p>\n<h4>Php serverside script<\/h4>\n<p>Lets take a look at a complete php example, task.php<\/p>\n<pre class=\"source-code\" >&lt;?php\r\n\/**\r\n\tEventSource is documented at \r\n\thttp:\/\/dev.w3.org\/html5\/eventsource\/\r\n*\/\r\n\r\n\/\/a new content type. make sure apache does not gzip this type, else it would get buffered\r\nheader(&#039;Content-Type: text\/event-stream&#039;);\r\nheader(&#039;Cache-Control: no-cache&#039;); \/\/ recommended to prevent caching of event data.\r\n\r\n\/**\r\n\tConstructs the SSE data format and flushes that data to the client.\r\n*\/\r\nfunction send_message($id, $message, $progress) \r\n{\r\n\t$d = array(&#039;message&#039; =&gt; $message , &#039;progress&#039; =&gt; $progress);\r\n\t\r\n\techo &quot;id: $id&quot; . PHP_EOL;\r\n\techo &quot;data: &quot; . json_encode($d) . PHP_EOL;\r\n\techo PHP_EOL;\r\n\t\r\n\t\/\/PUSH THE data out by all FORCE POSSIBLE\r\n\tob_flush();\r\n\tflush();\r\n}\r\n\r\n$serverTime = time();\r\n\r\n\/\/LONG RUNNING TASK\r\nfor($i = 0; $i &lt; 10; $i++)\r\n{\r\n\tsend_message($serverTime, &#039;server time: &#039; . date(&quot;h:i:s&quot;, time()) , ($i+1)*10); \r\n\t\r\n\t\/\/Hard work!!\r\n\tsleep(1);\r\n}\r\n\r\nsend_message($serverTime, &#039;TERMINATE&#039;);<\/pre>\t\t<div class=\"display-ad-unit mobile-wide bsa\" style=\"background:#fff3f3; height:315px;\">\n\n\n<!-- BinaryTides_S2S_InContent_ROS_Pos2 -->\n<style>\n\t@media only screen and (min-width: 0px) and (min-height: 0px) {\n\t\tdiv[id^=\"bsa-zone_1611334361252-4_123456\"] {\n\t\t\tmin-width: 300px;\n\t\t\tmin-height: 250px;\n\t\t}\n\t}\n\t@media only screen and (min-width: 640px) and (min-height: 480px) {\n\t\tdiv[id^=\"bsa-zone_1611334361252-4_123456\"] {\n\t\t\tmin-width: 300px;\n\t\t\tmin-height: 250px;\n\t\t}\n\t}\n<\/style>\n<div id=\"bsa-zone_1611334361252-4_123456\"><\/div>\n\n\n<\/div>\n<!-- Time: 0.00013494491577148, Pos: 4562, Key: ad_unit_2 -->\n\n\n<p>The send_message function generates messages to send to the client. The loop at the end indicates some long running task what sends out messages periodically. Note that we are sending a json encoded string in the data part of the event message. This is useful since we can send arrays or objects like that.<\/p>\n<p>Another important thing is the header. <strong>text\/event-stream<\/strong> is a content type of this data transfer. Its very useful to have a different content type so that web servers and browsers can handle the communication accordingly. Many websites configure mod_gzip in apache to compress all css, js, html, xml content. But make sure that it does not compress this event stream content type, or else it would get buffered. To further ensure that no buffering takes place inside php itself, we call ob_flush and flush to push the message out to the client as soon as possible.<\/p>\n<h4>Client Side<\/h4>\n<p>And next is the html file that initiates this task and reports the progress<\/p>\n<p>index.html<\/p>\n<pre class=\"source-code\" >&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n\t&lt;head&gt;\r\n\t\t&lt;meta charset=&quot;utf-8&quot; \/&gt;\r\n\t\t\r\n\t\t&lt;script&gt;\r\n\t\tvar source = &#039;THE SOURCE&#039;;\r\n\t\t\r\n\t\tfunction start_task()\r\n\t\t{\r\n\t\t\tsource = new EventSource(&#039;task.php&#039;);\r\n\t\t\t\r\n\t\t\t\/\/a message is received\r\n\t\t\tsource.addEventListener(&#039;message&#039; , function(e) \r\n\t\t\t{\r\n\t\t\t\tvar result = JSON.parse( e.data );\r\n\t\t\t\t\r\n\t\t\t\tadd_log(result.message);\r\n\t\t\t\t\r\n\t\t\t\tdocument.getElementById(&#039;progressor&#039;).style.width = result.progress + &quot;%&quot;;\r\n\t\t\t\t\r\n\t\t\t\tif(e.data.search(&#039;TERMINATE&#039;) != -1)\r\n\t\t\t\t{\r\n\t\t\t\t\tadd_log(&#039;Received TERMINATE closing&#039;);\r\n\t\t\t\t\tsource.close();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\t\r\n\t\t\tsource.addEventListener(&#039;error&#039; , function(e)\r\n\t\t\t{\r\n\t\t\t\tadd_log(&#039;Error occured&#039;);\r\n\t\t\t\t\r\n\t\t\t\t\/\/kill the object ?\r\n\t\t\t\tsource.close();\r\n\t\t\t});\r\n\t\t}\r\n\t\t\r\n\t\tfunction stop_task()\r\n\t\t{\r\n\t\t\tsource.close();\r\n\t\t\tadd_log(&#039;Interrupted&#039;);\r\n\t\t}\r\n\t\t\r\n\t\tfunction add_log(message)\r\n\t\t{\r\n\t\t\tvar r = document.getElementById(&#039;results&#039;);\r\n\t\t\tr.innerHTML += message + &#039;&lt;br&gt;&#039;;\r\n\t\t\tr.scrollTop = r.scrollHeight;\r\n\t\t}\r\n\t\t&lt;\/script&gt;\r\n\t&lt;\/head&gt;\r\n\t&lt;body&gt;\r\n\t\tThis is NOT AJAX\r\n\t\t&lt;br \/&gt;\r\n\t\t&lt;input type=&quot;button&quot; onclick=&quot;start_task();&quot;  value=&quot;Start Long Task&quot; \/&gt;\r\n\t\t&lt;input type=&quot;button&quot; onclick=&quot;stop_task();&quot;  value=&quot;Stop Task&quot; \/&gt;\r\n\t\t&lt;br \/&gt;\r\n\t\t&lt;br \/&gt;\r\n\t\t\r\n\t\tResults\r\n\t\t&lt;br \/&gt;\r\n\t\t&lt;div id=&quot;results&quot; style=&quot;border:1px solid #000; padding:10px; width:300px; height:200px; overflow:auto; background:#eee;&quot;&gt;&lt;\/div&gt;\r\n\t\t&lt;br \/&gt;\r\n\t\t\r\n\t\t&lt;div style=&quot;border:1px solid #ccc; width:300px; height:20px; overflow:auto; background:#eee;&quot;&gt;\r\n\t\t\t&lt;div id=&quot;progressor&quot; style=&quot;background:#07c; width:0%; height:100%;&quot;&gt;&lt;\/div&gt;\r\n\t\t&lt;\/div&gt;\r\n\t\t\r\n\t&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\t\t<div class=\"display-ad-unit mobile-wide bsa\" style=\"background:#fff3f3; height:315px;\">\n<!-- BinaryTides_S2S_InContent_ROS_Pos3 -->\n<style>\n\t@media only screen and (min-width: 0px) and (min-height: 0px) {\n\t\tdiv[id^=\"bsa-zone_1672330111515-1_123456\"] {\n\t\t\tmin-width: 300px;\n\t\t\tmin-height: 250px;\n\t\t}\n\t}\n\t@media only screen and (min-width: 640px) and (min-height: 480px) {\n\t\tdiv[id^=\"bsa-zone_1672330111515-1_123456\"] {\n\t\t\tmin-width: 300px;\n\t\t\tmin-height: 250px;\n\t\t}\n\t}\n<\/style>\n<div id=\"bsa-zone_1672330111515-1_123456\"><\/div>\n<\/div>\n<!-- Time: 5.793571472168E-5, Pos: 8193, Key: ad_unit_3 -->\n\n\n<p>The above is what was shown in the demo earlier. It handles the message event and updates an html element to indicate the progress. This is core of the event source api and is very straightforward to implement.<\/p>\n<h3>Websockets vs Server side events<\/h3>\n<p>Websockets is api meant for bi-directional communication between the browser and server. Unlike server send events, the websockets server allows the client to \"push\" messages to the connected server anytime, just like the server was doing in the above example.<\/p>\n<p>Bidirectional communication is something that is not always needed in web applications. It is useful in things like games, chat server etc. When only the server needs to send data and not the client, websockets is not necessary. Moreover web sockets requires a complete webserver to run that can speak the web socket protocol. This is a heavy requirement that cannot be easily put into existing applications.<\/p>\n<h3>Browser Support<\/h3>\n<p>At the time of writing this article, IE 10 the latest, had no support for EventSource. But there are other ways out. And the best one I found to be is <a href=\"http:\/\/www.codekites.com\/ajax-based-streaming-without-polling\/\">ajax streaming without polling<\/a>.<\/p>\n<p>There are other fallback techniques to imitate the EventSource object where it is not present, but they are more like hacks. Techniques like script tag streaming might produce reliable results depending on the case, but still scalability would be questionable. Check out the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Comet_(programming)\">wikipedia article on comet<\/a> and <a href=\"http:\/\/ajaxpatterns.org\/HTTP_Streaming\">ajaxpatterns.org on http streaming<\/a>.<\/p>\n<h3>Resources<\/h3>\n<a href=\"http:\/\/dev.w3.org\/html5\/eventsource\/\">http:\/\/dev.w3.org\/html5\/eventsource\/<\/a>\n\n<!-- SMARTADDR: No ad unit (ad_unit_4) was added at location: 11693. Content Length: 10598 -->\n<!-- SMARTADDR: No ad unit (ad_unit_5) was added at location: 11693. Content Length: 10693 -->","protected":false},"excerpt":{"rendered":"<p>Server sent events When running a long serverside task inside a web application it becomes very useful, if not necessary to report the progress of that task in realtime to the clientside, that is the browser. Earlier there was no easy way to do this and hacks had to be constructed to achieve such a&#8230; <span class=\"read-more\"><a href=\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":15958,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[539,545,322],"tags":[],"class_list":["post-3783","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html5-2","category-javascript","category-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Monitor progress of long running Php scripts with Html5 server sent events - BinaryTides<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Silver Moon\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/\",\"url\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/\",\"name\":\"Monitor progress of long running Php scripts with Html5 server sent events - BinaryTides\",\"isPartOf\":{\"@id\":\"https:\/\/www.binarytides.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.binarytides.com\/blog\/wp-content\/uploads\/2023\/09\/no-thumbnail.jpg\",\"datePublished\":\"2013-03-06T11:36:49+00:00\",\"dateModified\":\"2023-05-01T14:19:39+00:00\",\"author\":{\"@id\":\"https:\/\/www.binarytides.com\/#\/schema\/person\/ce24c6ddfa0368f9a08bcf46505884dd\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#primaryimage\",\"url\":\"https:\/\/www.binarytides.com\/blog\/wp-content\/uploads\/2023\/09\/no-thumbnail.jpg\",\"contentUrl\":\"https:\/\/www.binarytides.com\/blog\/wp-content\/uploads\/2023\/09\/no-thumbnail.jpg\",\"width\":1920,\"height\":1080},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.binarytides.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Monitor progress of long running Php scripts with Html5 server sent events\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.binarytides.com\/#website\",\"url\":\"https:\/\/www.binarytides.com\/\",\"name\":\"BinaryTides\",\"description\":\"News, Technology, Entertainment and more\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.binarytides.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.binarytides.com\/#\/schema\/person\/ce24c6ddfa0368f9a08bcf46505884dd\",\"name\":\"Silver Moon\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.binarytides.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/67ac3d58b656585dc0201e900a67f4197eb0c3ef2d1f83dd8f95a0b497cd97da?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/67ac3d58b656585dc0201e900a67f4197eb0c3ef2d1f83dd8f95a0b497cd97da?s=96&r=g\",\"caption\":\"Silver Moon\"},\"description\":\"A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at binarytides@gmail.com.\",\"url\":\"https:\/\/www.binarytides.com\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Monitor progress of long running Php scripts with Html5 server sent events - BinaryTides","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/","twitter_misc":{"Written by":"Silver Moon","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/","url":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/","name":"Monitor progress of long running Php scripts with Html5 server sent events - BinaryTides","isPartOf":{"@id":"https:\/\/www.binarytides.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#primaryimage"},"image":{"@id":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#primaryimage"},"thumbnailUrl":"https:\/\/www.binarytides.com\/blog\/wp-content\/uploads\/2023\/09\/no-thumbnail.jpg","datePublished":"2013-03-06T11:36:49+00:00","dateModified":"2023-05-01T14:19:39+00:00","author":{"@id":"https:\/\/www.binarytides.com\/#\/schema\/person\/ce24c6ddfa0368f9a08bcf46505884dd"},"breadcrumb":{"@id":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#primaryimage","url":"https:\/\/www.binarytides.com\/blog\/wp-content\/uploads\/2023\/09\/no-thumbnail.jpg","contentUrl":"https:\/\/www.binarytides.com\/blog\/wp-content\/uploads\/2023\/09\/no-thumbnail.jpg","width":1920,"height":1080},{"@type":"BreadcrumbList","@id":"https:\/\/www.binarytides.com\/monitor-progress-long-running-php-scripts-html5-server-sent-events\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.binarytides.com\/"},{"@type":"ListItem","position":2,"name":"Monitor progress of long running Php scripts with Html5 server sent events"}]},{"@type":"WebSite","@id":"https:\/\/www.binarytides.com\/#website","url":"https:\/\/www.binarytides.com\/","name":"BinaryTides","description":"News, Technology, Entertainment and more","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.binarytides.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.binarytides.com\/#\/schema\/person\/ce24c6ddfa0368f9a08bcf46505884dd","name":"Silver Moon","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.binarytides.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/67ac3d58b656585dc0201e900a67f4197eb0c3ef2d1f83dd8f95a0b497cd97da?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/67ac3d58b656585dc0201e900a67f4197eb0c3ef2d1f83dd8f95a0b497cd97da?s=96&r=g","caption":"Silver Moon"},"description":"A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at binarytides@gmail.com.","url":"https:\/\/www.binarytides.com\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/posts\/3783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/comments?post=3783"}],"version-history":[{"count":3,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/posts\/3783\/revisions"}],"predecessor-version":[{"id":14935,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/posts\/3783\/revisions\/14935"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/media\/15958"}],"wp:attachment":[{"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/media?parent=3783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/categories?post=3783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.binarytides.com\/wp-json\/wp\/v2\/tags?post=3783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}