{"id":56367,"date":"2022-07-10T03:01:41","date_gmt":"2022-07-09T17:01:41","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=56367"},"modified":"2022-07-10T09:23:43","modified_gmt":"2022-07-09T23:23:43","slug":"broadcast-channel-api-same-domain-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/broadcast-channel-api-same-domain-tutorial\/","title":{"rendered":"Broadcast Channel API Same Domain Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.php\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Broadcast Channel API Same Domain Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test_diffwb.jpg\" title=\"Broadcast Channel API Same Domain Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Broadcast Channel API Same Domain Tutorial<\/p><\/div>\n<p>Yesterday&#8217;s <a title='Broadcast Channel API Primer Tutorial' href='#bcapipt'>Broadcast Channel API Primer Tutorial<\/a>&#8216;s premise would have disappointed many as we outlined the restriction &#8230;<\/p>\n<blockquote cite='\/\/www.rjmprogramming.com.au\/ITblog\/broadcast-channel-api-primer-tutorial\/'><p>\nsame device, same web browser\n<\/p><\/blockquote>\n<p> &#8230; with our HTML and Javascript client facing <a target=_blank title='Broadcast Channel API information' href='https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Broadcast_Channel_API'>Broadcast Channel API<\/a> web application.<\/p>\n<p>But supposing we introduce &#8220;database&#8221; or &#8220;other data repository&#8221; thoughts?  That can ease that restriction to then be, merely &#8230;<\/p>\n<blockquote cite='\/\/www.rjmprogramming.com.au\/ITblog\/broadcast-channel-api-same-domain-tutorial\/'><p>\nsame domain\n<\/p><\/blockquote>\n<p> &#8230; which just means broadcasters and listeners access the <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.php-GETME\" title=\"broadcast_api_test.php\">&#8220;how we got there&#8221;<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.php-GETME\" title=\"broadcast_api_test.php\">&#8220;now PHP server facing&#8221; broadcast_api_test.php<\/a> new Broadcasting <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.php\" title=\"Click picture\">web application<\/a> incarnation.<\/p>\n<p>But no formal &#8220;database&#8221; connections here.  We make the PHP code itself be the &#8220;other data repository&#8221;, the new web application writing to itself, referencing the data of a particular Broadcast Channel in PHP records like &#8230;<\/p>\n<p>&lt;?php<br \/>\n<code><br \/>\n\/\/ AM 09:46:06 Saturday 9th of July 2022: bcn=yeswell msg=TGlzdGVuZXI6IFdlbGwsCm9r<br \/>\n<\/code><br \/>\n?&gt;<\/p>\n<p> &#8230; the message part <a target=_blank title='PHP base64_encode information' href='http:\/\/php.net\/manual\/en\/function.base64-encode.php'>base64_encode<\/a>d to avoid line feeds and carriage returns of the textarea inputting elements.<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/broadcast-channel-api-same-domain-tutorial\/'>Broadcast Channel API Same Domain Tutorial<\/a>.<\/p-->\n<hr>\n<p id='bcapipt'>Previous relevant <a target=_blank title='Broadcast Channel API Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/broadcast-channel-api-primer-tutorial\/'>Broadcast Channel API Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Broadcast Channel API Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.jpg\" title=\"Broadcast Channel API Primer Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Broadcast Channel API Primer Tutorial<\/p><\/div>\n<p>Broadcasting is a tried and trusted model of &#8230;<\/p>\n<ul>\n<li>information distribution<\/li>\n<li>entertainment distribution<\/li>\n<\/ul>\n<p> &#8230; and if you add in &#8220;listeners who can respond&#8221; (perhaps named and the broadcaster can re-respond) you can add &#8230;<\/p>\n<ul>\n<li>feedback<\/li>\n<li>collaboration<\/li>\n<li>sharing<\/li>\n<\/ul>\n<p> &#8230; into the mix.  Well, today, we have a <a target=_blank title='Broadcast Channel API information' href='https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Broadcast_Channel_API'>Broadcast Channel API<\/a> idea where same device, same web browser users can subscribe to a Broadcast Channel and join into <a target=_blank title='window.postMessage() information' href='https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/postMessage'>postMessage<\/a>() inspired functionality of this ilk.<\/p>\n<p><code><br \/>\n&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;title&gt;Broadcast API Usage - RJM Programming - July, 2022 ... thanks to https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Broadcast_Channel_API&lt;\/title&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;style&gt;<br \/>\n  td { vertical-align: top; }<br \/>\n  #ta { width: 98%; background-color: yellow; }<br \/>\n  #tab { width: 98%; background-color: lightblue; }<br \/>\n&lt;\/style&gt;<br \/>\n&lt;table border=20 style='width:100%;'&gt;<br \/>\n&lt;tr&gt;&lt;th contenteditable=true id=bname&gt;Broadcaster&lt;\/th&gt;&lt;th contenteditable=true id=lname&gt;Listener&lt;\/th&gt;&lt;\/tr&gt;<br \/>\n&lt;tr&gt;&lt;td id=blist&gt;<br \/>\n&lt;input style='width:100%;' id=itab type=text placeholder='RJM Programming Broadcast Channel Name of yours' value='' onblur='newone(this);'&gt;&lt;\/input&gt;<br \/>\n&lt;textarea id=tab placeholder='' value='' onblur='sthis(this);' rows=5 cols=80&gt;&lt;\/textarea&gt;<br \/>\n&lt;\/td&gt;<br \/>\n&lt;td id=btextarea&gt;<br \/>\n&lt;input id=ita style='width:100%;' type=text placeholder='RJM Programming Broadcast Channel Name of broadcaster to subscribe to' value='' onblur='onenew(this);'&gt;&lt;\/input&gt;<br \/>\n&lt;textarea id=ta onblur='sthis(this);' placeholder='' value='' rows=5 cols=80&gt;&lt;\/textarea&gt;<br \/>\n&lt;\/td&gt;&lt;\/tr&gt;<br \/>\n&lt;\/table&gt;<br \/>\n<br \/>\n&lt;script type='text\/javascript'&gt;<br \/>\n  var lastmsg='';<br \/>\n  let ourbc=null;<br \/>\n  let yourbc=null;<br \/>\n  let pbc=null;<br \/>\n  let bc=null;<br \/>\n  var wois=null;<br \/>\n<br \/> <br \/>\n  var ebc=location.search.split('bc=')[1] ? decodeURIComponent(location.search.split('bc=')[1].split('&')[0]).replace(\/\\+\/g,' ') : \"\";<br \/>\n  if (ebc.trim() != '') {<br \/>\n    \/\/const bc=null;<br \/>\n    document.getElementById('itab').placeholder=ebc;<br \/>\n    document.getElementById('ita').placeholder=ebc;<br \/>\n    document.getElementById('itab').value='';<br \/>\n    document.getElementById('ita').value='';<br \/>\n    document.getElementById('itab').onblur=function(event) { event.target.value=ebc; }<br \/>\n    document.getElementById('ita').onblur=function(event) { event.target.value=ebc; }<br \/>\n    document.getElementById('itab').setAttribute('readonly',true);<br \/>\n    document.getElementById('tab').setAttribute('readonly',true);<br \/>\n    document.getElementById('tab').style.display='none';<br \/>\n    yourbc = new BroadcastChannel(ebc);<br \/>\n    yourbc.onmessage = event =&gt; {<br \/>\n      if (minussc(event.data) != lastmsg) {<br \/>\n        \/\/alert('in with msg=' + event.data);<br \/>\n        \/\/document.getElementById('ta').value+=String.fromCharCode(10) + event.data.replace(lastmsg, '');<br \/>\n        document.getElementById('ta').value=String.fromCharCode(10) + event.data; \/\/.replace(lastmsg, '');<br \/>\n        document.getElementById('ta').title='' + new Date();<br \/>\n        document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));<br \/>\n        document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));<br \/>\n        if (yourbc) {<br \/>\n          \/\/yourbc.postMessage(document.getElementById('lname').innerHTML + ': ' + minussc(event.data)); \/\/.replace(lastmsg, ''));<br \/>\n          yourbc.postMessage(event.data); \/\/.replace(lastmsg, ''));<br \/>\n          window.opener.andback(); \/\/ wois.focus();<br \/>\n        }<br \/>\n        lastmsg=minussc(event.data);<br \/>\n      }<br \/>\n    };<br \/>\n    wois=window.opener;<br \/>\n  }<br \/>\n<br \/> <br \/>\n  function andback() {<br \/>\n    \/\/alert('Am back');<br \/>\n    window.focus();<br \/>\n  }<br \/>\n<br \/> <br \/>\n  function oureval(inv) {<br \/>\n    var tabi=document.getElementById('tab').value.split(String.fromCharCode(10));<br \/>\n    var tai=document.getElementById('ta').value.split(String.fromCharCode(10));<br \/>\n    return Math.max(eval(2 + eval('' + tabi.length)), eval(2 + eval('' + tai.length)));<br \/>\n  }<br \/>\n<br \/>\n  function newone(iv) {<br \/>\n   if (iv.value.trim() != '') {<br \/>\n    \/\/ Connection to a broadcast channel<br \/>\n    \/\/if (ourbc) {<br \/>\n    \/\/  ourbc.close();<br \/>\n    \/\/}<br \/>\n    \/\/const bc = new BroadcastChannel(iv.value);<br \/>\n    bc = new BroadcastChannel(iv.value);<br \/>\n    pbc=bc;<br \/>\n    ourbc=bc;<br \/>\n    document.getElementById('ita').setAttribute('readonly',true);<br \/>\n    document.getElementById('ta').setAttribute('readonly',true);<br \/>\n    document.getElementById('ta').style.display='none';<br \/>\n    ebc=iv.value;<br \/>\n    document.getElementById('itab').placeholder=ebc;<br \/>\n    document.getElementById('ita').placeholder=ebc;<br \/>\n    document.getElementById('itab').value='';<br \/>\n    document.getElementById('ita').value='';<br \/>\n    document.getElementById('itab').onblur=function(event) { event.target.value=ebc; }<br \/>\n    document.getElementById('ita').onblur=function(event) { event.target.value=ebc; }<br \/>\n    bc.onmessage = event =&gt; {<br \/>\n      if (minussc(event.data) != lastmsg) {<br \/>\n        \/\/document.getElementById('tab').value+=String.fromCharCode(10) + event.data.replace(lastmsg, '');<br \/>\n        document.getElementById('tab').value=String.fromCharCode(10) + event.data; \/\/.replace(lastmsg, '');<br \/>\n        document.getElementById('tab').title='' + new Date();<br \/>\n        document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));<br \/>\n        document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));<br \/>\n        if (bc) {<br \/>\n          \/\/bc.postMessage(document.getElementById('bname').innerHTML + ': ' + minussc(event.data)); \/\/.replace(lastmsg, ''));<br \/>\n          bc.postMessage(event.data); \/\/.replace(lastmsg, ''));<br \/>\n          wois.focus();<br \/>\n        }<br \/>\n        lastmsg=minussc(event.data);<br \/>\n      }<br \/>\n    };<br \/>\n    wois=window.open(document.URL.split('#')[0].split('?')[0] + '?bc=' + encodeURIComponent(iv.placeholder), '_blank');<br \/>\n   }<br \/>\n  }<br \/>\n<br \/> <br \/>\n  function onenew(iv) {<br \/>\n    yourbc = new BroadcastChannel(iv.value);<br \/>\n    yourbc.onmessage = event =&gt; {<br \/>\n      if (minussc(event.data) != lastmsg) {<br \/>\n        \/\/document.getElementById('tab').value+=String.fromCharCode(10) + event.data.replace(lastmsg, '');<br \/>\n        document.getElementById('tab').value=String.fromCharCode(10) + event.data; \/\/.replace(lastmsg, '');<br \/>\n        document.getElementById('tab').title='' + new Date();<br \/>\n        document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));<br \/>\n        document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));<br \/>\n        if (ourbc) {<br \/>\n          \/\/ourbc.postMessage(document.getElementById('bname').innerHTML + ': ' + minussc(event.data)); \/\/.replace(lastmsg, ''));<br \/>\n          ourbc.postMessage(event.data); \/\/.replace(lastmsg, ''));<br \/>\n          wois.focus();<br \/>\n        }<br \/>\n        lastmsg=minussc(event.data);<br \/>\n      }<br \/>\n    };<br \/>\n  }<br \/>\n<br \/> <br \/>\n  function minussc(insa) {<br \/>\n    if (insa.indexOf(': ') != -1) {<br \/>\n      return insa.replace(insa.split(': ')[0] + ': ','');<br \/>\n    }<br \/>\n    return insa;<br \/>\n  }<br \/>\n<br \/> <br \/>\n  function sthis(iv) {<br \/>\n    if (iv.value.trim() != '') {<br \/>\n    if (yourbc && !pbc) {<br \/>\n      yourbc.postMessage(document.getElementById('lname').innerHTML + ': ' + minussc(iv.value));<br \/>\n      document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));<br \/>\n      document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));<br \/>\n      iv.placeholder+=String.fromCharCode(10) + iv.value;<br \/>\n      iv.value='';<br \/>\n    } else if (bc) {<br \/>\n      \/\/alert('at broadcaster with msg=' + iv.value);<br \/>\n      \/\/bc=newone(document.getElementById('itab'));<br \/>\n      bc.postMessage(document.getElementById('bname').innerHTML + ': ' + minussc(iv.value));<br \/>\n      document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));<br \/>\n      document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));<br \/>\n      iv.placeholder+=String.fromCharCode(10) + iv.value;<br \/>\n      iv.value='';<br \/>\n    }<br \/>\n    }<br \/>\n  }<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<br \/>\n<\/code><\/p>\n<p> &#8230; as a first draft &#8220;proof of concept&#8221; <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.html_GETME\">broadcast_api_test.html<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/broadcast_api_test.html\">Broadcast API web application<\/a> you can try for yourself.<\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d56362' onclick='var dv=document.getElementById(\"d56362\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/broadcast\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d56362' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d56367' onclick='var dv=document.getElementById(\"d56367\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/php\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d56367' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday&#8217;s Broadcast Channel API Primer Tutorial&#8216;s premise would have disappointed many as we outlined the restriction &#8230; same device, same web browser &#8230; with our HTML and Javascript client facing Broadcast Channel API web application. But supposing we introduce &#8220;database&#8221; &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/broadcast-channel-api-same-domain-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,14,37],"tags":[88,1653,2661,1710,4027,4026,198,212,1604,1985,1709,2442,290,576,652,2114,932,2227,997,2407,1055,1122,1133,1262,1319],"class_list":["post-56367","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-api","tag-base64","tag-base64_encode","tag-broadcast","tag-broadcast-channel-api","tag-broadcaster","tag-channel","tag-client","tag-collaboration","tag-comment","tag-communication","tag-contenteditable","tag-data","tag-html","tag-javascript","tag-listener","tag-php","tag-postmessage","tag-programming","tag-record","tag-repository","tag-server","tag-share","tag-textarea","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/56367"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=56367"}],"version-history":[{"count":6,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/56367\/revisions"}],"predecessor-version":[{"id":56373,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/56367\/revisions\/56373"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=56367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=56367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=56367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}