{"id":32785,"date":"2017-09-11T03:01:40","date_gmt":"2017-09-10T17:01:40","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=32785"},"modified":"2017-09-15T08:33:02","modified_gmt":"2017-09-14T22:33:02","slug":"socket-io-node-js-whiteboard-quiz-collaboration-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/socket-io-node-js-whiteboard-quiz-collaboration-tutorial\/","title":{"rendered":"Socket.IO Node.js Whiteboard Quiz Collaboration Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/socketio_whiteboard_quiz.jpg\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Socket.IO Node.js Whiteboard Quiz Collaboration Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/socketio_whiteboard_quiz.jpg\" title=\"Socket.IO Node.js Whiteboard Quiz Collaboration Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Socket.IO Node.js Whiteboard Quiz Collaboration Tutorial<\/p><\/div>\n<p>Yesterday&#8217;s <a title='Socket.IO Node.js Whiteboard Application Primer Tutorial' href='#s.ion.wapt'>Socket.IO Node.js Whiteboard Application Primer Tutorial<\/a> set us up for using the dynamic duo of &#8230;<\/p>\n<ul>\n<li>Socket.IO &#8230; use of sockets<\/li>\n<li>Node.js &#8230; local web server<\/li>\n<\/ul>\n<p> &#8230; to collaborate with one HTML(5) <a target=_blank title='HTML5 canvas element information from w3schools ... thanks' href='http:\/\/www.w3schools.com\/html\/html5_canvas.asp'>canvas<\/a> element per client on http:\/\/localhost:3000 sharing canvas graphical data off each other.<\/p>\n<p>Yesterday was a &#8220;no holds barred&#8221; share (and collaboration) of each other&#8217;s canvas data, but today we add in an existant (but modified for the purpose (though you wouldn&#8217;t know visiting <a target=_blank title='PHP Bcmath Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/php-bcmath-primer-tutorial\/'>PHP Bcmath Primer Tutorial<\/a>&#8216;s <a target=_blank title='got_big_numbers.php' href='http:\/\/www.rjmprogramming.com.au\/PHP\/got_big_numbers.php'>live run<\/a> using its PHP <a target=_blank title='got_big_numbers.php' href='http:\/\/www.rjmprogramming.com.au\/PHP\/got_big_numbers.php-GETME'>got_big_numbers.php<\/a> changed in <a target=_blank title='got_big_numbers.php' href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/PHP\/got_big_numbers.php-GETME'>this way<\/a>)) Mathematics Quiz Game, whose functionality is totally optional as far as the user is concerned, and which we house at the Socket.IO Node.js created webpage in an HTML <a target=_blank title='HTML iframe element information from w3schools' href='http:\/\/www.w3schools.com\/tags\/tag_iframe.asp'>iframe<\/a> element.<\/p>\n<p>If you closely examine today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/socketio_whiteboard_quiz.jpg\" title=\"Tutorial picture\">tutorial picture<\/a> contents, or this snippet of index.html code &#8230;<\/p>\n<p><code><br \/>\n&lt;iframe id=\"quizzer\" src=\"http:\/\/localhost:8888\/got_big_numbers.php\" title=\"Test your collaborators\"&gt;&lt;\/iframe&gt;<br \/>\n<\/code><\/p>\n<p> &#8230; you may immediately see an issue here communicating between that (<a target=_blank title='MAMP Mac OS X local Apache\/PHP web server landing page' href='http:\/\/www.mamp.info'>MAMP<\/a> PHP web application) and our Socket.IO Node.js client on <i>http:\/\/localhost:3000<\/i> and yes, this investigation of file reading and writing and Javascript DOM client pre-emptive style code we talk about came to nothing that great, until we stumbled upon this <a target=_blank title='Useful webpage, thanks' href='https:\/\/stackoverflow.com\/questions\/1612177\/are-http-cookies-port-specific'>useful webpage<\/a>, thanks, that put me onto the (admittedly kludgy feeling) solution of using <a target=_blank title='Cookie information from w3schools' href='http:\/\/www.w3schools.com\/js\/js_cookies.asp'><i>HTTP Cookies<\/i><\/a> to manage the communications, and it worked a treat for this purpose.  On a non-local web server, you&#8217;d probably have to make other arrangements, perhaps introducing a database (like <a target=_blank title='MongoDB' href='https:\/\/www.mongodb.com\/'>MongoDB<\/a>, perhaps) into the equation.  Be that as it may, this HTTP Cookie method has a nice feel to it, and we based our cookie GET\/SET paradigm on the good code at <a target=_blank title='Useful link, thanks' href='https:\/\/stackoverflow.com\/questions\/4825683\/how-do-i-create-and-read-a-value-from-cookie'>this useful link<\/a>, so, thanks for that.<\/p>\n<p>In layperson&#8217;s terms the maths quiz functionality works &#8230;<\/p>\n<ul>\n<li>at the beginning of a Socket.IO Node.js execution (cycle), index.js (the server), in its &#8230;<br \/>\n<code><br \/>\nio.on('connection', onConnection);<br \/>\n<\/code><br \/>\n&#8230; <i>onConnect<\/i> &#8220;connection&#8221; event logic (where it establishes functionality for the other relevant events such &#8220;disconnect&#8221; and &#8220;question&#8221;) &#8230; can <i>io.sockets.emit(&#8220;gameon&#8221;, { receivers: &#8216;everyone&#8217;});<\/i> when there are more than one user logged in (and therefore collaboration makes sense) or <i>io.sockets.emit(&#8220;gameoff&#8221;, { receivers: &#8216;everyone&#8217;});<\/i> otherwise &#8230;<\/li>\n<li>that is used by main.js at the Socket.IO client to set the HTTP Cookie called &#8220;gameon&#8221; with a value of &#8220;y&#8221; (for &#8220;gameon&#8221;, and setting in play the <a target=_blank title='Javascript setTimeout method information from w3schools' href='http:\/\/www.w3schools.com\/jsref\/met_win_settimeout.asp'><i>setTimeout<\/i><\/a> Javascript listener function &#8220;keepalookout()&#8221;, and which you can squint to see in our <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/socketio_whiteboard_quiz.jpg\" title=\"Tutorial picture\">tutorial picture<\/a>) and &#8220;n&#8221; otherwise &#8230;<\/li>\n<li>and this same HTTP Cookie &#8220;gameon&#8221; can be read by our MAMP PHP child web application, which changes its looks accordingly (and also sets in play the <a target=_blank title='Javascript setTimeout method information from w3schools' href='http:\/\/www.w3schools.com\/jsref\/met_win_settimeout.asp'><i>setTimeout<\/i><\/a> Javascript listener function &#8220;check_for_supervision()&#8221; to keep checking), including adding in a new HTML input type=button &#8220;Challenge&#8221; if the HTTP Cookie &#8220;gameon&#8221; starts with &#8220;y&#8221; &#8230; and &#8230;<\/li>\n<li>should a user fill in the two numbers and an operator above this button and then click this &#8220;Challenge&#8221; button, it sets in play &#8230;<\/li>\n<li>the MAMP PHP child web application appends to the HTTP Cookie &#8220;gameon&#8221; information about the maths quiz question the user wants to challenge all other users sharing and collaborating the game with &#8230;<\/li>\n<li>and back at the main.js of the Socket.IO client this HTTP Cookie &#8220;gameon&#8221; change is detected by the &#8220;keepalookout()&#8221; listener (talked about above) which goes about updating its HTTP Cookie &#8220;gameon&#8221;, and populating the question and answer client HTML elements (keeping the answer to themselves in a Javascript global var<font size=1>iable<\/font>, and awaiting optional user filling in of the HTML input type=number &#8220;answer&#8221; field), as well as (socket emit) sending &#8230;<br \/>\n<code><br \/>\n socket.emit(\"question\", whatq.split(' ')[eval(-1 +  whatq.split(' ').length)]);<br \/>\n<\/code><br \/>\n &#8230; the message to &#8230;<\/li>\n<li>the Socket.IO server receives the &#8220;question&#8221; event and &#8230;<br \/>\n<code><br \/>\n  socket.on('question', function(msg){<br \/>\n    <b>io.emit('question', msg);<\/b><br \/>\n  });<br \/>\n<\/code><br \/>\n &#8230; <b>emits<\/b> this same message to all those other collaborators so that at &#8230;<\/li>\n<li>these other collaborators update their HTTP Cookie &#8220;gameon&#8221; as well as populating the question and answer client HTML elements  (keeping the answer to themselves in a Javascript global var<font size=1>iable<\/font>, and awaiting optional user filling in of the HTML input type=number &#8220;answer&#8221; field) &#8230; which has as part of its design &#8230;<\/li>\n<li><i>onblur<\/i> and <i>onchange<\/i> event logics trap the user answers that may or may not happen, and client Javascript code checks the answer against that Javascript global var<font size=1>iable<\/font> to update the (relevant user&#8217;s) score<\/li>\n<\/ul>\n<p>The rest of the code looks like &#8230;<\/p>\n<ul>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.js--GETME'>index.js<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.js--GETME'>this way<\/a>)\n<\/li>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.html--GETME'>index.html<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.html--GETME'>this way<\/a>)\n<\/li>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/main.js--GETME'>main.js<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/main.js--GETME'>this way<\/a>)\n<\/li>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/style.css--GETME'>style.css<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/style.css--GETME'>this way<\/a>)\n<\/li>\n<\/ul>\n<p>The <a target=_blank title='PHP Bcmath Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/php-bcmath-primer-tutorial\/'>PHP Bcmath Primer Tutorial<\/a> code being the PHP that it is you would also want installed the Apache\/PHP\/MySQL local web server we love around here called <a target=_blank title='MAMP Mac OS X local Apache\/PHP web server landing page' href='http:\/\/www.mamp.info'>MAMP<\/a>, and hope that it and Node.js don&#8217;t start any fisticuffs at 3am?!<\/p>\n<hr>\n<p id='s.ion.wapt'>Previous relevant <a target=_blank title='Socket.IO Node.js Whiteboard Application Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/socket.io-node.js-whiteboard-application-primer-tutorial\/'>Socket.IO Node.js Whiteboard Application 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\/Mac\/NodeJs\/Whiteboard\/socketio_whiteboard.jpg\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Socket.IO Node.js Whiteboard Application Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/socketio_whiteboard.jpg\" title=\"Socket.IO Node.js Whiteboard Application Primer Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Socket.IO Node.js Whiteboard Application Primer Tutorial<\/p><\/div>\n<p>We&#8217;re building on another great Socket.IO Node.js basis web application project (with <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/package.json_GETME'>package.json<\/a>) by Damien Arrachequesne (of MIT) on <a target=_blank title='Socket.IO Node.js Whiteboad web application by Damien Arrachequesne' href='https:\/\/github.com\/socketio\/socket.io\/tree\/master\/examples\/whiteboard'>GitHub<\/a>, thanks, called &#8220;Whiteboard&#8221;, which is a socket based collaborative web application &#8230; downloaded and assembled into place on the MacBook Pro and compiled via &#8230;<\/p>\n<p><code><br \/>\n$ npm i && npm start<br \/>\n<\/code><\/p>\n<p> &#8230; and (re)started via &#8230;<\/p>\n<p><code><br \/>\n$ node index<br \/>\n<\/code><\/p>\n<p> &#8230; as per the usual Node.js way &#8230; using an HTML(5) <a target=_blank title='HTML5 canvas element information from w3schools ... thanks' href='http:\/\/www.w3schools.com\/html\/html5_canvas.asp'>canvas<\/a> to share the drawing of &#8230;<\/li>\n<ul>\n<li>scribble based lines in a variety of colours &#8230; and we added, today &#8230;<\/li>\n<li>discrete click\/touch lines in a wider variety of colours<\/li>\n<li>discrete click\/touch rectangles<\/li>\n<li>discrete click\/touch circles<\/li>\n<li>discrete click\/touch top left image (via an image URL) placement<\/li>\n<li>discrete click\/touch top left and bottom right image placement<\/li>\n<\/ul>\n<p>Of course, where this can have useful implications are for games where, effectively, a single screen is shared and graphically collaborated to, by one or more users.<\/p>\n<p>What&#8217;s the go integrating &#8230;<\/p>\n<ul>\n<li>a new &#8220;discrete click\/touch&#8221; set of functionality &#8230; into an existant &#8230;<\/li>\n<li>scribble based line set of functionality<\/li>\n<\/ul>\n<p>?  Totally in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/main.js-GETME'>main.js<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/main.js-GETME'>this way<\/a>) we <b>added\/changed<\/b> the jQuery Javascript event code as below &#8230;<\/p>\n<p><code><br \/>\n  <b>var numbermd = 0, lastwas = 0;<br \/>\n  var prevx = 0, prevy = 0;<\/b><br \/>\n<br \/>\n  function onMouseDown(e){<br \/>\n    <b>numbermd++;<\/b><br \/>\n    drawing = true;<br \/>\n    <b>lastwas = -1;<br \/>\n    if (numbermd &gt; 1) {<br \/>\n      if (current.drawmode == 'rectangle') {<br \/>\n        drawRectangle(prevx, prevy, e.clientX, e.clientY, current.color, true);<br \/>\n        numbermd = 0;<br \/>\n      } else if (current.drawmode == 'circle') {<br \/>\n        drawCircle(prevx, prevy, e.clientX, e.clientY, current.color, true);<br \/>\n        numbermd = 0;<br \/>\n      } else if (current.drawmode == 'image2') {<br \/>\n        drawImage(prevx, prevy, e.clientX, e.clientY, current.color, true);<br \/>\n        numbermd = 0;<br \/>\n      } else {<br \/>\n        drawLine(prevx, prevy, e.clientX, e.clientY, current.color, true);<br \/>\n        numbermd = 1;<br \/>\n      }<br \/>\n    } else if (current.drawmode == 'image1') {<br \/>\n      drawImage(e.clientX, e.clientY, -1, -1, current.color, true);<br \/>\n      numbermd = 0;<br \/>\n    }<\/b><br \/>\n    current.x = e.clientX;<br \/>\n    current.y = e.clientY;<br \/>\n    <b>prevx = current.x;<br \/>\n    prevy = current.y;<\/b><br \/>\n  }<br \/>\n<br \/>\n  function onMouseUp(e){<br \/>\n    if (!drawing) { return; }<br \/>\n    <b>if (lastwas != -1) numbermd = 0;<\/b><br \/>\n    drawing = false;<br \/>\n    <b>if (lastwas != -1)<\/b> drawLine(current.x, current.y, e.clientX, e.clientY, current.color, true);<br \/>\n    <\/b>lastwas = 0;<\/b><br \/>\n  }<br \/>\n<br \/>\n  function onMouseMove(e){<br \/>\n    if (!drawing) { return; }<br \/>\n    <b>numbermd = 0;<br \/>\n    lastwas = 1;<\/b><br \/>\n    drawLine(current.x, current.y, e.clientX, e.clientY, current.color, true);<br \/>\n    current.x = e.clientX;<br \/>\n    current.y = e.clientY;<br \/>\n  }<br \/>\n<\/code><\/p>\n<p>Do you see a lot the same with the architecture of yesterday&#8217;s  <a title='Socket.IO Node.js Chat Application Primer Tutorial' href='#s.ion.capt'>Socket.IO Node.js Chat Application Primer Tutorial<\/a>?  They share the use of sockets.  They share the collaborative screen sharing approach.  They share the idea of a single server process, serving a lot of clients using a local Node web server URL of http:\/\/localhost:3000 as well.  Once you start identifying similarities in things, you build up thoughts regarding how to construct things, because you&#8217;ve &#8220;seen&#8221; something similar in the past.  Various platforms have various strengths, and just because this collaborative screen sharing socket using approach has been great over the last two web applications, in our eyes, don&#8217;t think there is only ever one way to do things.  Being introduced to alternative ways is not going backwards at any time, as long as you are strong in working out what the client wants, and short of that, with a flexible client, what you are comfortable to use as a development platform, so long as you have sussed out it is a physically possible alternative.<\/p>\n<p>Other code parts were &#8230;<\/p>\n<ul>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.js-GETME'>index.js<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.js-GETME'>this way<\/a>)\n<\/li>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.html-GETME'>index.html<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/index.html-GETME'>this way<\/a>)\n<\/li>\n<li><a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/style.css-GETME'>style.css<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Whiteboard\/style.css-GETME'>this way<\/a>)\n<\/li>\n<\/ul>\n<p>You can also see this play out at WordPress 4.1.1&#8217;s <a target=_blank  href='https:\/\/www.rjmprogramming.com.au\/ITblog\/socket.io-node.js-whiteboard-application-primer-tutorial\/'>Socket.IO Node.js Whiteboard Application Primer Tutorial<\/a>.<\/p>\n<hr>\n<p id='s.ion.capt'>Previous relevant <a target=_blank title='Socket.IO Node.js Chat Application Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/socket.io-node.js-chat-application-primer-tutorial\/'>Socket.IO Node.js Chat Application 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\/Mac\/NodeJs\/Chat\/socketio_chat.pdf\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Socket.IO Node.js Chat Application Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/socketio_chat.jpg\" title=\"Socket.IO Node.js Chat Application Primer Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Socket.IO Node.js Chat Application Primer Tutorial<\/p><\/div>\n<p>Network <a target=_blank title='Network socket information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Network_socket'>sockets<\/a> are a powerful communication tool for software developers &#8230;<\/p>\n<blockquote cite=\"https:\/\/en.wikipedia.org\/wiki\/Network_socket\"><p>\nA network socket is an internal endpoint for sending or receiving data at a single node in a computer network. Concretely, it is a representation of this endpoint in networking software (protocol stack), such as an entry in a table (listing communication protocol, destination, status, etc.), and is a form of system resource.\n<\/p><\/blockquote>\n<p>Team that with the brilliant <a target=_blank title='Node.js' href='https:\/\/nodejs.org\/'>Node.js<\/a> local web server product (we last talked about with  <a title='Node.js and Node Local Web Server Primer Tutorial' href='#n.nlwspt'>Node.js and Node Local Web Server Primer Tutorial<\/a>) based real time engine <a target=_blank title='socket.io' href='https:\/\/socket.io\/'>socket.io<\/a> code, and you can build an application, like today&#8217;s chat application very speedily, and reliably &#8230; thanks, everybody.<\/p>\n<p>So, today&#8217;s chat application &#8230;<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/XN0EAPBu3tk\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p> &#8230; started as <a target=_blank title='socket.io' href='https:\/\/socket.io\/'>socket.io<\/a>&#8216;s &#8220;Hello World&#8221; &#8220;foot in the door&#8221; (with that one prerequisite that you should install Node.js (as we did at that tutorial link above some time back)) that gets you places fast, then we recommend delving into their very interesting follow up suggestions, expressed by &#8230;<\/p>\n<ul>\n<li><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/socketio_chat.pdf\" title=\"Click picture\">Hello World<\/a> <a target=_blank title='Hello World chat application on http:\/\/localhost:3000 Node.js local web server' href='https:\/\/socket.io\/get-started\/chat\/'>&#8220;by the book&#8221;<\/a> (http:\/\/localhost:3000 Node.js local web server) <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/package.json_GETME'>package.json<\/a> and <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.js_GETME'>index.js<\/a> and <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.js_GETME'>index.js<\/a> (remember how Node.js has Javascript client and Javascript server &#8230; wow!!!) and <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.html_GETME'>index.html<\/a> &#8230; then &#8230;<\/li>\n<li>after work on Hello World follow up questions <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.js-GETME'>index.js<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.js-GETME'>this way<\/a>) and <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.html-GETME'>index.html<\/a> (changed in <a target=_blank href='http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/Chat\/index.html-GETME'>this way<\/a>) &#8230; attending to &#8230;<br \/>\n<blockquote cite=\"https:\/\/socket.io\/get-started\/chat\/\">\n<ol>\n<li>Broadcast a message to connected users when someone connects or disconnects <font size=1>&#8230; user messages are all prefixed by a user count and they can display a user list on request, as discussed below<\/font><\/li>\n<li>Add support for nicknames <font size=1>&#8230; we start with a robotic (username) nomenclature (eg. [Chatter_1504844291]) and allow user to change name via a designated field or via &#8220;I am cedric popples&#8221; type of message<\/font><\/li>\n<li>Don\u2019t send the same message to the user that sent it himself. Instead, append the message directly as soon as he presses enter. <font size=1>&#8230; user can override this (sensible) functionality by placing themselves into an &#8220;(only for [cedric popples])&#8221; type of list as required<\/font><\/li>\n<li>Add \u201c{user} is typing\u201d functionality <font size=1>&#8230; trap the jQuery <i>onkeyup<\/i> event logic as per $(&#8216;form&#8217;).keyup(function(event) { [more code here] });<\/font><\/li>\n<li>Show who\u2019s online <font size=1>&#8230; we make this a <i>client action required<\/i> piece of functionality<\/font><\/li>\n<li>Add private messaging <font size=1>&#8230; we allow for  &#8220;(only for [cedric popples])&#8221; and  &#8220;(not for [cedric popples])&#8221; type lists<\/font><\/li>\n<li>Share your improvements! <font size=1>&#8230; as linked to above, there is also a feature to adjust the message list&#8217;s &#8220;odd&#8221; element colour via &#8230;<br \/>\n<code><br \/>\nCSS:<br \/>\n#messages li:nth-child(odd) { background: #eee; }<br \/>\njQuery Javascript:<br \/>\n    $('#imyc').change(function(){<br \/>\n      $('#messages li:nth-child(odd)').css('background-color', $('#imyc').val());<br \/>\n      document.getElementById('imyc').style.display='none';<br \/>\n    });<br \/>\nHTML:<br \/>\n&lt;input type=\"color\" value=\"lightgray\" id=\"imyc\" style=\"display:none;\" title=\"Colour of odd messages\"&gt;&lt;\/input&gt;<br \/>\n<\/code><br \/>\n<\/font><\/li>\n<\/ol>\n<\/blockquote>\n<\/li>\n<\/ul>\n<p> &#8230; and eventually the way of <a target=_blank title='socket.io' href='https:\/\/socket.io\/'>socket.io<\/a> sinks in <font size=1>(the verdict? &#8230; it&#8217;s great!)<\/font>, and you can see where its role might be in the <a target=_blank title='Solution stack information from Wikipedia' href='https:\/\/en.wikipedia.org\/wiki\/Solution_stack'>Full-Stack Developer<\/a> roles that package these software modules up, and which encourage the use of products like <a target=_blank title='Ansible OpenSource project' href='https:\/\/github.com\/ansible\/ansible'>Ansible<\/a> to manage deployment procedures.  But for me the question still is &#8230; can Socket.IO put the toaster on and can Node.JS get out the plate while Ansible answers all the client&#8217;s difficult questions to end up with that &#8220;breakfast before you know you wanted it&#8221; project we&#8217;ve let slip for the last month &#8230; wouldn&#8217;t you know it, <a target=_blank title='Vagrant VMWare integration' href='https:\/\/www.vagrantup.com\/'>Vagrant<\/a> up and walked off with the toast before it got to the client.<\/p>\n<p>This web application design, along with so many other platforms, revolves around the concept of a local web server, and if you want to read about Socket.IO in this context, in relation to others we&#8217;ve talked about in this &#8220;Hello World&#8221; frame of reference, the blog post to visit is <a target=_blank title='Cassini++ WebServer Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/cassini-webserver-primer-tutorial'>Cassini++ WebServer Primer Tutorial<\/a>.<\/p>\n<hr>\n<p id='n.nlwspt'>Previous relevant <a target=_blank title='Node.js and Node Local Web Server Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/node.js-and-node-local-web-server-primer-tutorial\/'>Node.js and Node Local Web Server 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\/Mac\/NodeJs\/index.html\"><img decoding=\"async\" style=\"float:left;border: 15px solid pink;\" alt=\"Node.js and Node Local Web Server Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/node_js-114of.jpg\" title=\"Node.js and Node Local Web Server Primer Tutorial\"  id='oiis' onmouseover=\" this.src=this.src.replace('-114of.j','-94of.xj').replace('-94of.j','-95of.xj').replace('-95of.j','-96of.xj').replace('-96of.j','-97of.xj').replace('-97of.j','-98of.xj').replace('-98of.j','-99of.xj').replace('-99of.j','-100of.xj').replace('-100of.j','-101of.xj').replace('-101of.j','-102of.xj').replace('-102of.j','-103of.xj').replace('-103of.j','-104of.xj').replace('-104of.j','-105of.xj').replace('-105of.j','-106of.xj').replace('-106of.j','-107of.xj').replace('-107of.j','-108of.xj').replace('-108of.j','-109of.xj').replace('-109of.j','-110of.xj').replace('-110of.j','-111of.xj').replace('-111of.j','-112of.xj').replace('-112of.j','-113of.xj').replace('-113of.j','-114of.xj').replace('.xj','.j'); \" \/><\/a><p class=\"wp-caption-text\">Node.js and Node Local Web Server Primer Tutorial<\/p><\/div>\n<p>We love PHP for web server work, but readily acknowledge &#8230;<\/p>\n<ol>\n<li>PHP is losing out, in popularity terms, to frameworks like <a target=_blank title='Node.js installation download webpage' href='https:\/\/nodejs.org\/en\/download\/'>Node.js<\/a> (which we introduce to you today with a &#8220;Hello World&#8221; tutorial, where you&#8217;ll see its Javascript (yes, Javascript), in (server side) action)<\/li>\n<li>Node.js is a framework that has Javascript running on the server side, a pretty powerful scenario<\/li>\n<\/ol>\n<p> &#8230; and so, a great divide in programming (frameworks) is developing.  Personally, I like the division of &#8220;language&#8221; between PHP server code and Javascript client code, but can see the &#8220;cuteness&#8221; of just thinking &#8220;Javascript&#8221;, and so, today, we show you a Node.js installation on our MacBook Pro using Mac OS X, though you will see, if you take a skeg at our <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/index.html\" title='Click picture'>slideshow<\/a> that Node.js is very much cross-platform by nature.<\/p>\n<p>If you read this blog, you&#8217;ll (hopefully) have seen how fond we PHP&#8217;ers are here regarding the &#8230;<\/p>\n<p><code><br \/>\n<a target=_blank title='MAMP local web server for Mac OS X' href='https:\/\/www.mamp.info\/'><i>MAMP<\/i><\/a> local web server on port <i>8888<\/i> supporting <i>PHP<\/i> and a <i>MySql<\/i> database on port 8889 on a MacBook Pro Mac OS X using web browsers<br \/>\n<\/code><\/p>\n<p> &#8230; well with Node.js, the scenario is &#8230;<\/p>\n<p><code><br \/>\n<i>Node<\/i> local web server on port <i>3000<\/i> supporting <i>Javascript (Node.js like)<\/i> and a <i>MySql<\/i> database (still) on port 8889 (in our case because we co-exist with MAMP and have MAMP running and access its socket file to make the MySql connection) if co-existing with (running) MAMP or port 3306 (it looks like) if there is no MAMP involved<br \/>\n<\/code><\/p>\n<p>And so, today, we first show a client &#8220;facing&#8221; &#8220;Hello World&#8221; scenario of just showing &#8230; &#8220;Hello World&#8221; &#8230; a web application &#8220;frontend&#8221; if you will.<\/p>\n<p>Then we got a MySql database involved &#8230; a web application &#8220;backend&#8221; if you will &#8230; and we hope if you are a regular reader at this blog &#8230; even though this blog posting <i>may have<\/i> &#8220;rocked your world&#8221; with (Node.js) Javascript getting involved at the server side (though we did warn you with our very first Javascript DOM focused tutorial called <a target=_blank title='JavaScript and the DOM Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/javascript-and-the-dom-tutorial\/'>JavaScript and the DOM Tutorial<\/a>?! &#8230; it&#8217;s taken a while for the &#8220;wheel&#8221; to turn!) &#8230; databases always involve server side code, and so we update the <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/hello_world.js_GETME\" title=\"hello_world.js\">hello_world.js<\/a> to include showing the results of our MySql query &#8230;<\/p>\n<p><code><br \/>\nSELECT * FROM CIRCLE, POINT WHERE pointid=originid<br \/>\n<\/code><\/p>\n<p> &#8230; linked, &#8220;back in the day&#8221; with this <a target=_blank title='MySql Stored Procedures Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/mysql-stored-procedures-primer-tutorial\/'>MySql Stored Procedures Primer Tutorial<\/a> &#8230; and after some dead ends where we didn&#8217;t know whether to have MAMP running or not &#8230; the slideshow is &#8220;warts &#8216;n all&#8221; &#8230; we end up finding out that <i>Node\/Node.js (Javascript)\/MySql<\/i> can co-exist and be an alternative to our cherished <i>MAMP (local Apache web server)\/PHP\/MySql<\/i> &#8220;power triplet&#8221;.  To have a few methods to try things can&#8217;t be that bad &#8230; huh?!  Stay tuned please.<\/p>\n<p>We (almost) leave you with the Open Source links that made the research (culminating in today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/NodeJs\/node_js-114of.jpg\" title='Tutorial picture'>tutorial picture<\/a>) possible &#8230; thanks &#8230;<\/p>\n<ul>\n<a target=_blank title='Node.js installation download webpage' href='https:\/\/nodejs.org\/en\/download\/'>Node.js installer download webpage &#8230; you download, then for Mac OS X, run package installer<\/a><\/li>\n<p><a target=_blank title='Node.js installation after download and package file install' href='http:\/\/expressjs.com\/en\/starter\/installing.html'>First steps after Node.js download and package installation, about further installation steps at Mac OS X Terminal application&#8217;s command line environment, regarding how to create Node\/Node.js project (directories) and (sub-project-)install steps<\/a><\/li>\n<p><a target=_blank title='MySql connection' href='https:\/\/codeforgeek.com\/2015\/01\/nodejs-mysql-tutorial\/'>Useful regarding (first draft) Node.js connection to MySql example<\/a><\/li>\n<p><a target=_blank title='npm install mysql' href='http:\/\/stackoverflow.com\/questions\/18134411\/cannot-find-module-mysql-node-js'>Useful link leading us to understand that we needed &#8216;npm install mysql&#8217; (via npm package registry) to install MySql module for Node\/Node.js<\/a><\/li>\n<p><a target=_blank title='MySql connection MAMP socket idea' href='http:\/\/stackoverflow.com\/questions\/30266221\/node-js-mysql-error-connect-econnrefused'>Useful regarding Node.js connection to MySql showing how MAMP socket can be used for co-existance<\/a><\/li>\n<p><a target=_blank title='PHP vs Node.js discussion' href='http:\/\/www.infoworld.com\/article\/2866712\/php\/php-vs-node-js-an-epic-battle-for-developer-mind-share.html'>Discussion of PHP vs Node.js<\/a><\/li>\n<\/ul>\n<p>Another player in this realm of thinking is Ruby (on Rails), and with this in mind, take a read of <a target=_blank title='Ruby on Rails Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/ruby-on-rails-primer-tutorial\/'>Ruby on Rails Primer Tutorial<\/a> where port 3000 is used with a local web server arrangement, as well.  Finally, if all this &#8220;web server&#8221; talk interests you as much as us, we&#8217;ve been compiling &#8220;web server&#8221; talk, so to speak into this one <a target=_blank title='Cassini++ WebServer Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/cassini-webserver-primer-tutorial'>Cassini++ WebServer Primer Tutorial<\/a> blog posting, where Node.js thinking from today has been added &#8230; Cassini++ ? &#8230; Cassini is the simplest (Windows) local web server we can think of, and we work discussions up from that.  That tutorial also mentions <a target=_blank title='Mojito Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/mojito-primer-tutorial'>Mojito Primer Tutorial<\/a> which also shows Javascript on both sides of the ledger with Node.js getting involved.<\/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='#d21201' onclick='var dv=document.getElementById(\"d21201\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/hello-world\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d21201' 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='#d32746' onclick='var dv=document.getElementById(\"d32746\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/chat\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d32746' 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='#d32774' onclick='var dv=document.getElementById(\"d32774\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/tutorial\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d32774' 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='#d32785' onclick='var dv=document.getElementById(\"d32785\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/cookies\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d32785' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday&#8217;s Socket.IO Node.js Whiteboard Application Primer Tutorial set us up for using the dynamic duo of &#8230; Socket.IO &#8230; use of sockets Node.js &#8230; local web server &#8230; to collaborate with one HTML(5) canvas element per client on http:\/\/localhost:3000 sharing &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/socket-io-node-js-whiteboard-quiz-collaboration-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":[184,1860,264,558,576,2323,587,590,652,663,714,744,840,932,997,1029,1126,1164,1319,1411,2322],"class_list":["post-32785","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-canvas","tag-cookie","tag-cookies","tag-hello-world","tag-html","tag-if-this-was-interesting-you-may-be-interested-in-this-too","tag-iframe","tag-image","tag-javascript","tag-jquery","tag-local-web-server","tag-mamp","tag-node-js","tag-php","tag-programming","tag-realtime","tag-settimeout","tag-socket","tag-tutorial","tag-web-server","tag-whiteboard"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/32785"}],"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=32785"}],"version-history":[{"count":21,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/32785\/revisions"}],"predecessor-version":[{"id":32884,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/32785\/revisions\/32884"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=32785"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=32785"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=32785"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}