<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< meta name = "generator" content = "Asciidoctor 2.0.10" >
< meta name = "description" content = "Intro and Install" >
< meta name = "keywords" content = "IoT" >
< meta name = "author" content = "Apostolos rootApostolos@swarmlab.io" >
< title > IoT swarm implementation !< / title >
< link rel = "stylesheet" href = "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700" >
< style >
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment @import statement to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
:not(pre)>code.nobreak{word-wrap:normal}
:not(pre)>code.nowrap{white-space:nowrap}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
table.tableblock{max-width:100%;border-collapse:separate}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
td.tableblock>.content>:last-child.sidebarblock{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot,table.frame-ends{border-width:1px 0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
< / style >
< link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" >
< / head >
< body class = "article toc2 toc-right" >
< div id = "header" >
< h1 > IoT swarm implementation !< / h1 >
< div class = "details" >
< span id = "author" class = "author" > Apostolos rootApostolos@swarmlab.io< / span > < br >
< / div >
< div id = "toc" class = "toc2" >
< div id = "toctitle" > Πίνακας περιεχομένων< / div >
< ul class = "sectlevel1" >
< li > < a href = "#_intro" > 1. Intro< / a > < / li >
< li > < a href = "#_prepare_installation" > 2. Prepare installation< / a >
< ul class = "sectlevel2" >
< li > < a href = "#_install_docker" > 2.1. Install docker< / a > < / li >
< li > < a href = "#_clone_iot_swarm_implementation_example" > 2.2. Clone IoT swarm implementation example< / a >
< ul class = "sectlevel3" >
< li > < a href = "#_webclient_tree" > 2.2.1. Webclient tree< / a > < / li >
< li > < a href = "#_iot_server_tree" > 2.2.2. IoT server tree< / a > < / li >
< / ul >
< / li >
< li > < a href = "#_control_services" > 2.3. Control services< / a >
< ul class = "sectlevel3" >
< li > < a href = "#_start_iot_server" > 2.3.1. start IoT server< / a > < / li >
< li > < a href = "#_stop_iot_server" > 2.3.2. stop IoT server< / a > < / li >
< li > < a href = "#_start_iot_client" > 2.3.3. start IoT client< / a > < / li >
< li > < a href = "#_stop_iot_client" > 2.3.4. stop IoT client< / a > < / li >
< li > < a href = "#_start_iot_client_n" > 2.3.5. start IoT client-n< / a > < / li >
< li > < a href = "#_stop_iot_client_n" > 2.3.6. stop IoT client-n< / a > < / li >
< li > < a href = "#_start_iot_webclient" > 2.3.7. start IoT webclient< / a > < / li >
< li > < a href = "#_stop_iot_webclient" > 2.3.8. stop IoT webclient< / a > < / li >
< li > < a href = "#_stop_all_services" > 2.3.9. stop All services< / a > < / li >
< / ul >
< / li >
< li > < a href = "#_use_webclient" > 2.4. Use webclient< / a >
< ul class = "sectlevel3" >
< li > < a href = "#_send_data_in_request_body_with_get" > 2.4.1. send data in request body with GET< / a > < / li >
< li > < a href = "#_using_sockets_to_send_and_receive_data" > 2.4.2. Using Sockets to send and receive data< / a > < / li >
< / ul >
< / li >
< / ul >
< / li >
< li > < a href = "#_technologies" > 3. Technologies< / a >
< ul class = "sectlevel2" >
< li > < a href = "#_mvc" > 3.1. MVC< / a > < / li >
< li > < a href = "#_microservices_architecture" > 3.2. Microservices Architecture< / a > < / li >
< / ul >
< / li >
< li > < a href = "#_software" > 4. Software< / a >
< ul class = "sectlevel2" >
< li > < a href = "#_client_site_pc" > 4.1. Client site (PC)< / a >
< ul class = "sectlevel3" >
< li > < a href = "#_vue" > 4.1.1. Vue< / a > < / li >
< li > < a href = "#_vuex" > 4.1.2. Vuex< / a > < / li >
< li > < a href = "#_using_axios_to_consume_apis" > 4.1.3. Using Axios to Consume APIs< / a > < / li >
< li > < a href = "#_using_socket_io_to_consume_websocket" > 4.1.4. Using socket.io to Consume Websocket< / a > < / li >
< / ul >
< / li >
< li > < a href = "#_clientserver_site_iot_device" > 4.2. Client/Server site (IoT device)< / a >
< ul class = "sectlevel3" >
< li > < a href = "#_nodejs" > 4.2.1. Nodejs< / a > < / li >
< li > < a href = "#_socket_io" > 4.2.2. socket.io< / a > < / li >
< li > < a href = "#_express" > 4.2.3. express< / a > < / li >
< li > < a href = "#_nosql" > 4.2.4. NoSQL< / a > < / li >
< / ul >
< / li >
< / ul >
< / li >
< li > < a href = "#_example_application" > 5. Example Application< / a >
< ul class = "sectlevel2" >
< li > < a href = "#_client_site" > 5.1. Client site< / a >
< ul class = "sectlevel3" >
< li > < a href = "#_main_config" > 5.1.1. main (config)< / a > < / li >
< li > < a href = "#_app_load" > 5.1.2. App (load)< / a > < / li >
< li > < a href = "#_create_compoment" > 5.1.3. Create compoment< / a > < / li >
< li > < a href = "#_use_your_component" > 5.1.4. Use your component< / a > < / li >
< li > < a href = "#_sockets" > 5.1.5. Sockets< / a > < / li >
< li > < a href = "#_create_store" > 5.1.6. create store< / a > < / li >
< / ul >
< / li >
< li > < a href = "#_server_site" > 5.2. Server site< / a > < / li >
< li > < a href = "#_iot_device" > 5.3. IoT Device< / a > < / li >
< / ul >
< / li >
< / ul >
< / div >
< / div >
< div id = "content" >
< div id = "preamble" >
< div class = "sectionbody" >
< div class = "paragraph" >
< p > < br > < / p >
< / div >
< / div >
< / div >
< div class = "sect1" >
< h2 id = "_intro" > 1. Intro< / h2 >
< div class = "sectionbody" >
< div class = "sidebarblock" >
< div class = "content" >
< div class = "title" > Intro IoT server< / div >
< div class = "ulist" >
< ul >
< li >
< p > software use< / p >
< / li >
< li >
< p > what will be covered< / p >
< / li >
< li >
< p > etc< / p >
< / li >
< / ul >
< / div >
< / div >
< / div >
< div class = "paragraph" >
< p > We will be trying to create a swarm implementation that will allow communication between all of the members/nodes.< / p >
< / div >
< div class = "admonitionblock note" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-note" title = "Note" > < / i >
< / td >
< td class = "content" >
< div class = "paragraph" >
< div class = "title" > Imaging a swarm< / div >
< p > < span class = "image" > < img src = "data:image/png;base64,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
< / div >
< div class = "paragraph" >
< p > To undertand this better lets look at the picture bellow and imagine that red dots are iot devices that can send and receive and black ones are clients that gather data.< / p >
< / div >
< div class = "paragraph" >
< div class = "title" > Architecture of swarm communication< / div >
< p > < span class = "image" > < img src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALAAAAE9CAYAAACr7ujsAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wsYESkvTArmGAAAIABJREFUeNrsvXlYVPfZ//9CFoEB2fd9Z9iGEWQRUFnEXRtXTExi1DSmTZu2aZ6mvZrvlTZ9mqZJrNmTGhPNZlSMGHFHEEEFAdl3ZF+HVXbX+f2RZ+YXIirIAKPyvi4v4yGcOXM+73Of+35/7kVFKpVKmcIUHlBMm7oFU5gi8BSmMEXgKUxh9FCbugVTGA26u7tJS0ujvLwcPT09AgMDcXFxmSLwFJQfV65c4ciRI2zbto2srCyMjY1ZtmwZv/nNbxCLxVMuxBSUG+3t7cTHx5OVlQVAW1sbX3zxBa+//jo5OTlTBJ6C8lvgnp6e244fPHiQhISEKQJPQblx/fp1rl+/ftvxGTNmoKOjM0XgKSg3HB0dmT17Nubm5kPIu2TJEmbNmjUVxE1BuWFsbMzatWvp6Ohg7969GBsbEx0dzeOPP46fn98Ugaeg/HB3d2fx4sVcvHiROXPm8Kc//QkDA4NJu54pF2IK9wUbGxu8vb0nlbxTBJ7CfaG2thYDAwMcHR0n/VqmCDyFUaO4uJiOjo5JUx6mCDyF+4ZMC3Z2dsba2nrSr0dhQVxqaio5OTmYmZlhbGyMh4cHZmZmUyv+kKGiooK6ujqEQuGk+78KI3Bqair//ve/ycvLQyAQIBAIePbZZ3n22WenVvwhQ1ZWFk1NTejq6irF9YyZwMXFxezatYvExET6+vrkx62trQkODsbLy2tq1R8y/1dNTU0p3AeF+MDt7e1UV1cPIS9Aa2srLS0tUyv+EPq/fn5+uLu7PxwEvlNJnYqKytSKP2QoLy+nvr4eDw8P7O3tHw4CC4VCvL29hz0+5T48XGhra0MqlSqFfKYwAhsbG7Ny5UrWrVuHqamp/LiJicmUCvGQobq6Gl1dXaXxfwFUX3vttdfGehITExN8fX2ZO3cuISEhDA4OUl1djb29PQ4ODlMr/xCgpqaGHTt2oKamxtKlS4cYqwdahQDQ1tZGKBQiFArp7+9ncHCQ999/n/j4eDw9PZXmy07h/lFUVER1dTULFizAysrq4XEhhiPzqlWrCA8P5+zZs1y8eHFq9R8S2NnZ4eXlhb6+/sNLYNkXffrppzEzMyM2NpbCwsKp1X/A0dXVha2trdKoD+NKYAB/f3/mzZtHRkYGZ86cmWLAA07e7Oxs1NXVlS4wHzcCCwQC5s6di729PbGxsSQnJ08x4QFFeXk5OTk5WFtbY2dn92gQGMDDw4Nf/epXaGtrc+TIEVpbWyf9C7e1tXHhwgXS09Pp6OhQSsLIEmaUBbJ1Uyb9V6EqxN2s8Lx58ygsLCQ5OZmMjAwWL148aV/23Llz7N27l4KCAqZNm4aPjw+PP/44/v7+k74QHR0dZGVlkZeXR3Z2NhYWFmzcuBFPT89Jv7aqqipmzJihVOrDhBD4pyTOyMggNjYWBwcHhELhhH/RkpISPv/8c/bt20dvby8AGRkZXL9+HQMDA5ycnCZ1IS5evMh7773HuXPn6O7uxsDAgJ6eHn7729/i4eExqddWVFTE9OnTsbS0VDoCT0hCu6enJ4sWLaKyspLY2NhJcSXq6+spKyuTkxd+7PNVUlJCU1PTpC9ERkaGnLwAnZ2d7N+/n7S0tEkP4Hp7e3F1dVVKCzwhBBYIBCxdupQ5c+aQnp4ub02kDDA2NsbQ0FApXAgZeX96LDs7m7y8vNt+NlEoKyujr68PBwcH9PT0Hk0CA5iamrJkyRI0NTVJTk6mra1twok6XAWBo6MjNjY2k74Qw5XoGBoaUlxczH/+8x/+/ve/c/z48QkncllZGQKBQCmtLygoF2KkMDAwoL6+nmPHjmFsbIyPj8+EfVFtbW16enooKytDVVUVkUjE2rVrWbdunVKI80ZGRty4cYPq6mq6u7txdnbmiSeeIDIykuvXr5OamkpmZiatra1cuXIFgUDAjBkzxv26YmNjaW9vZ968eUrpA09oYxOBQMDatWspKCjgyJEjE5oYLVtssVjMnDlz8PT0RCgUYmFhoRQL4eTkxObNm3F2dqahoQEnJyfmzp2LtbU1HR0dzJs3j6SkJEpLS0lLS8PS0pJ58+YxZ86ccSWWRCLB0NBQaTMLVSZjyEtCQgKffPIJYrGY5557DmNj43H/zOLiYl599VXc3d155ZVXlFLTvBdk1S+ZmZmcOXOGq1ev4uzsjIODA2KxGE9PT4XWqlVVVfH6668TERHBhg0blPKeTEprqaCgIC5evMiFCxeYNWsW0dHR4/6Zp06dor29HbFY/ECSV+ZmGBkZ4efnR3h4OLm5uWRlZXHkyBESExOZNWsWXl5eiMVihbxZCgsL0dTUVErXYVIJrKOjQ3h4OJmZmXz00UcIBAJCQkLG7fNaW1vJy8vDx8dnXD9nIuHq6oqrqysRERFkZGSQlJREQUEB586dw9ramnnz5hEaGjomInd0dCAQCJRSfZiUIO7nAd3g4CBJSUkAiEQitLW1x+WzkpKSyMvLY+HChZPWBnQ8g1NnZ2fEYjGurq5oaWnR3NxMUVERhYWFVFZWcvPmTfT09NDQ0BjVuffv34+6ujpz5sxRWhJPGoE1NDSwsrKitbWV/Px8bG1tx2U3rLW1lS+//BJjY2NWr179wLoPIyGylZUVs2bNIigoCAMDAyorK0lNTSUrK4vm5mbU1NRGTOTOzk6+/fZbRCIR4eHhdHZ2kpCQwI0bN5SqQGHSCCxzJbS1tUlLS2NgYGBcrHB+fj5JSUn4+fkRFhbGowBtbW1cXFyYOXMmlpaWSKVSqqqqyMjIIDc3l66uLgwNDe/6MOfm5pKXl4eDgwOqqqrExcXx3//+Fzs7u2GLeB9JAstciZqaGo4fP46ZmZnCK5ljY2Pp6upiyZIlSh2MjBeRXV1dmTNnDk5OTvT19ZGZmUl+fj6XL1+mu7sbFRUVtLS0brPKp0+fpqenBx8fHy5dukRaWhoikYj58+crlQVWUYZZyeXl5bz66qtoaGjw17/+FVdXV4Wct6ioiO3bt+Ph4cGWLVseWvdhtPckJyeHjIwMpFIpqqqq2NjYEBYWRn19PdnZ2cycOZOzZ89SWlrK6tWr6e/vx9bWlrCwsAnZPJlUC5yfn8+HH37I999/z+DgICYmJvd0C4yMjBgYGCApKYlbt27h7u6uEFfixIkTVFRUEBkZOSkZcMoIExMTvL298fPzw8rKiu7uboqKijh37hy/+Ne/eKm4mIyMDPLy8rCwsEBVVZXZs2cTEBCgdOQFQKpAJCQkSFetWiU1NjaWCgQCqbe3t3TPnj0j+t3Gxkbpxo0bpa6urtL9+/eP+VokEon0xRdflP71r3+VNjU1SadwZ+Tn50ujo6OlndraQ/7Y2tpK//jHP0orKiqU9toVmsxz4cIFjh07RltbG319feTn53PkyBFKS0vv+bsWFhasXbsWAwMD4uPjqaioGNO1pKWl0dHRgZ+f35CpOlP4/1FZWUlaWhp5eXnDxge5bW0cPHhw0jLhRgKFbWRIJBJqamro7+8fcry5uZm2tjbc3NzueY7Q0FAWLlzIgQMHOH/+PM7OzvctnZ0+fRo7OzuCg4OnmMqPmxL19fX09fVRWVmJRCKhsLCQ+vp6CgsL76jQpDY3c2Wc9HmlIrC2tjZaWlq3HS8oKCA1NRV3d3eMjIzueg5dXV3Wr19PQUEBe/fuxd3dnYCAgPt6E5SWlrJu3bpHtr1VRUUFEomEy5cvI5FIaG1tlSsPjY2NqKioYG1tja2tLX19fXR0dCA2NSVbIhlynv9ZuZJ/K/FOnMIIrKOjw7Jly8jKyuL8+fPAjznAbm5unD17lt7eXp588sl7Kgxubm4sWbKE999/n+PHj+Ps7DzqhPOsrCwMDAyUSq8cT6I2NzcDcPnyZVpaWlBRUaGoqIiGhgaampqYNm0aNjY2csKGh4fj5OSEoaEhAwMDuLq6Ym1tzYED
< / div >
< div class = "ulist" >
< ul >
< li >
< p > Red Node: Sensor Node and Gateway Role< / p >
< / li >
< li >
< p > Black and Red Node: Sensor Node - Client< / p >
< / li >
< / ul >
< / div >
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > < strong > To make our life easier at this task we will be using the following tools… ​ < / strong > < / p >
< / div >
< / div >
< / div >
< div class = "sect1" >
< h2 id = "_prepare_installation" > 2. Prepare installation< / h2 >
< div class = "sectionbody" >
< div class = "sect2" >
< h3 id = "_install_docker" > 2.1. < a href = "http://docs.swarmlab.io/SwarmLab-HowTos/labs/Howtos/docker/install.adoc.html" target = "_blank" rel = "noopener" > Install docker< / a > < / h3 >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
< div class = "paragraph" >
< p > < strong > Docker< / strong > is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers.< / p >
< / div >
< div class = "paragraph" >
< p > Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels< / p >
< / div >
< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_clone_iot_swarm_implementation_example" > 2.2. Clone IoT swarm implementation example< / h3 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > git clone https://git.swarmlab.io:3000/zeus/iot-swarm-example.git
cd iot-swarm-example< / code > < / pre >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_webclient_tree" > 2.2.1. Webclient tree< / h4 >
< div class = "listingblock" >
< div class = "title" > base dir Webclient< / div >
< div class = "content" >
< pre class = "highlight" > < code class = "language-bash" data-lang = "bash" > src/browser-client/src/
├── App.vue < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
├── assets
│ ├── css
│ │ └── themify-icons.css
│ ├── fonts
│ │ ├── glyphicons-halflings-regular.448c34a.woff2
│ │ ├── glyphicons-halflings-regular.e18bbf6.ttf
│ │ ├── glyphicons-halflings-regular.f4769f9.eot
│ │ ├── glyphicons-halflings-regular.fa27723.woff
│ │ ├── themify.eot
│ │ ├── themify.svg
│ │ ├── themify.ttf
│ │ └── themify.woff
│ └── logo.png
├── components < i class = "conum" data-value = "4" > < / i > < b > (4)< / b >
│ ├── doclive
│ │ ├── AdhocView.vue
│ │ └── runLlo.vue
│ └── DocLive.vue
├── main.js < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
└── store
├── index.js
└── modules
└── create_pipelineLLO.js < i class = "conum" data-value = "3" > < / i > < b > (3)< / b > < / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > load App< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > App config< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > Vuex and Rest calls< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "4" > < / i > < b > 4< / b > < / td >
< td > Components< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_iot_server_tree" > 2.2.2. IoT server tree< / h4 >
< div class = "listingblock" >
< div class = "title" > base dir IoT server< / div >
< div class = "content" >
< pre class = "highlight" > < code class = "language-bash" data-lang = "bash" > src/IoT/llo/
├── bclient.js
├── client.js
├── iotclient.js < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
└── iotserver.js < i class = "conum" data-value = "1" > < / i > < b > (1)< / b > < / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > IoT server< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > IoT client< / td >
< / tr >
< / table >
< / div >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_control_services" > 2.3. Control services< / h3 >
< div class = "sect3" >
< h4 id = "_start_iot_server" > 2.3.1. start IoT server< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./start-iotserver.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_stop_iot_server" > 2.3.2. stop IoT server< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./stop-iotserver.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_start_iot_client" > 2.3.3. start IoT client< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./start-iotclient.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_stop_iot_client" > 2.3.4. stop IoT client< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./stop-iotclient.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_start_iot_client_n" > 2.3.5. start IoT client-n< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./start-iotclient-n.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_stop_iot_client_n" > 2.3.6. stop IoT client-n< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./stop-iotclient-n.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_start_iot_webclient" > 2.3.7. start IoT webclient< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./start-iotwebclient.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_stop_iot_webclient" > 2.3.8. stop IoT webclient< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./stop-iotwebclient.sh< / code > < / pre >
< / div >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_stop_all_services" > 2.3.9. stop All services< / h4 >
< div class = "listingblock bash" >
< div class = "content" >
< pre class = "highlight" > < code > cd iot-swarm-example
./stop-all.sh< / code > < / pre >
< / div >
< / div >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_use_webclient" > 2.4. Use webclient< / h3 >
< div class = "paragraph" >
< p > open in Browser: < a href = "http://localhost:8080" class = "bare" > http://localhost:8080< / a > < / p >
< / div >
< div class = "paragraph" >
< p > and< / p >
< / div >
< div class = "paragraph" >
< p > open Web Developer with ctrl+shift+K< / p >
< / div >
< div class = "sect3" >
< h4 id = "_send_data_in_request_body_with_get" > 2.4.1. send data in request body with GET< / h4 >
< div class = "paragraph" >
< p > type text in < em > "Get iot Data"< / em > and klick on it< / p >
< / div >
< div class = "paragraph" >
< p > See < em > "action"< / em > in< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > < strong > Console< / strong > in browser< / p >
< / li >
< li >
< p > and in Linux < strong > Terminal< / strong > < / p >
< / li >
< / ul >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_using_sockets_to_send_and_receive_data" > 2.4.2. Using Sockets to send and receive data< / h4 >
< div class = "paragraph" >
< p > type text in editor box< / p >
< / div >
< div class = "paragraph" >
< p > See < em > "action"< / em > in< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > < strong > Console< / strong > in browser< / p >
< / li >
< li >
< p > and in Linux < strong > Terminal< / strong > < / p >
< / li >
< / ul >
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "sect1" >
< h2 id = "_technologies" > 3. Technologies< / h2 >
< div class = "sectionbody" >
< div class = "sect2" >
< h3 id = "_mvc" > 3.1. MVC< / h3 >
< div class = "paragraph" >
< p > A core principle of the MVC pattern is the view layer’ s ignorance with respect to the model layer. Views are dumb objects. They only know how to present data to the user. They don’ t know or understand what they are presenting.< / p >
< / div >
< div class = "paragraph" >
< p > MVC: Division across three code components only: Model, View, and Controller. … ​ Microservices: An app is divided into a set of specialized classes that interact with each other using APIs. This model is being used by companies like Netflix, Spotify, and eBay.< / p >
< / div >
< div class = "paragraph" >
< p > Model: This part manages the data on your site. Its role is to retrieve the raw information from the database, organize, and assemble it so that it can be processed by the controller.< / p >
< / div >
< div class = "paragraph" >
< p > View: This part focuses on the display. It is here where the data recovered by the model will be presented to the user.< / p >
< / div >
< div class = "paragraph" >
< p > Controller: This part manages the logic of the code and makes decisions. When the user interacts with the view, the request is processed by the controller.< / p >
< / div >
< div class = "paragraph" >
< p > It waits for the user to interact with the view to retrieve the request. Thus, it is the controller that will define the display logic, and display the next view on the screen.< / p >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_microservices_architecture" > 3.2. Microservices Architecture< / h3 >
< div class = "paragraph" >
< p > Microservices can be defined as an improvement, a kind of refinement, of what we know as service-oriented architecture (SOA).< / p >
< / div >
< div class = "paragraph" >
< p > In this architecture, a large application is made in the form of small monofunctional modules. Each microservice is autonomous.< / p >
< / div >
< div class = "paragraph" >
< p > Microservices do not share a data layer. Each has its own database and load balancer. So that each of these services can be deployed, adjusted, and redeployed individually without jeopardizing the integrity of an application.< / p >
< / div >
< div class = "paragraph" >
< p > As a result, you will only need to change a couple self-contained services instead of having to redeploy the entire application.< / p >
< / div >
< / div >
< / div >
< / div >
< div class = "sect1" >
< h2 id = "_software" > 4. Software< / h2 >
< div class = "sectionbody" >
< div class = "sect2" >
< h3 id = "_client_site_pc" > 4.1. Client site (PC)< / h3 >
< div class = "sect3" >
< h4 id = "_vue" > 4.1.1. Vue< / h4 >
< div class = "admonitionblock note" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-note" title = "Note" > < / i >
< / td >
< td class = "content" >
< div class = "title" > vuejs< / div >
< div class = "paragraph" >
< p > Vue.js is an open-source, progressive JavaScript framework for building user interfaces (UIs) and single-page applications.< / p >
< / div >
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > < strong > Library modularization< / strong > using a framework is common in frontend development.< / p >
< / div >
< div class = "paragraph" >
< p > What differentiates Vue.js from other alternatives is:< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > its < strong > “high decoupling”< / strong > , how easy it is to extend functionalities, and how well all parts work once more modules are included.< / p >
< / li >
< / ul >
< / div >
< div class = "paragraph" >
< p > For example, if we want to organize and render small visual components, all we need is Vue.js’s ‘core’ library.
It is not necessary to include additional libraries.< / p >
< / div >
< div class = "paragraph" >
< p > As the application grows,< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > we have libraries to manage < strong > routes< / strong > such as < strong > ‘vue-router’< / strong > ,< / p >
< / li >
< li >
< p > libraries to manage the global state such as < strong > ‘vuex’< / strong > < / p >
< / li >
< li >
< p > and libraries to build responsive web applications such as < strong > ‘bootstrap-vue’< / strong > .< / p >
< / li >
< li >
< p > Additionally, if our application needs to be optimized or needs good SEO, we can include the < strong > ‘vue-server-rendering’< / strong > library.< / p >
< / li >
< / ul >
< / div >
< div class = "paragraph" >
< p > In the following figure, we can see how the libraries we just mentioned are progressively included, from a small SPA to multi-page applications (MPA).< / p >
< / div >
< div class = "imageblock" >
< div class = "content" >
< img src = "data:image/png;base64,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
< / div >
< / div >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
The name of the framework – Vue – is the same phonetically in English as view, and it corresponds to the traditional Model-View-Controller (MVC) architecture
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > React and Angular are other Frameworks similar to vuejs< / p >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_vuex" > 4.1.2. Vuex< / h4 >
< div class = "paragraph" >
< p > Vuex is a state management pattern + library for Vue.js applications.< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.< / p >
< / li >
< li >
< p > It also integrates with Vue’ s official devtools extension
to provide advanced features such as zero-config time-travel debugging and state snapshot export / import.< / p >
< / li >
< / ul >
< / div >
< div class = "admonitionblock note" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-note" title = "Note" > < / i >
< / td >
< td class = "content" >
< div class = "title" > What is a "State Management Pattern"?< / div >
< div class = "paragraph" >
< p > < strong > Let’ s start with a simple Vue counter app:< / strong > < / p >
< / div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-javascript" data-lang = "javascript" > new Vue({
// state
data () { < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
return {
count: 0
}
},
// view
template: ` < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
< div> {{ count }}< /div>
`,
// actions
methods: { < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
increment () {
this.count++
}
}
})< / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > The state, the source of truth that drives our app;< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > The view, a declarative mapping of the state;< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > The actions, the possible ways the state could change in reaction to user inputs from the view.< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > This is a simple representation of the concept of "one-way data flow":< / p >
< / div >
< / td >
< / tr >
< / table >
< / div >
< div class = "imageblock" >
< div class = "content" >
< img src = "data:image/png;base64,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
< / div >
< / div >
< div class = "imageblock" >
< div class = "content" >
< img src = "data:image/png;base64,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
< / div >
< / div >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
< a href = "https://scrimba.com/learn/vuex" target = "_blank" rel = "noopener" > Online Vuex cources< / a >
< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_using_axios_to_consume_apis" > 4.1.3. Using Axios to Consume APIs< / h4 >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
Axios is a library for http communication, making ajax requests, and so on.
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > < a href = "https://github.com/axios/axios" target = "_blank" rel = "noopener" > See more< / a > < / p >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_using_socket_io_to_consume_websocket" > 4.1.4. Using socket.io to Consume Websocket< / h4 >
< div class = "paragraph" >
< p > Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It supports multiple transports, such as WebSockets, Flash sockets, long polling and more, automatically falling back when a transport fails< / p >
< / div >
< div class = "paragraph" >
< p > < a href = "https://socket.io/" target = "_blank" rel = "noopener" > See more info here: Socket.io< / a > < / p >
< / div >
< div class = "paragraph" >
< p > Vue Packages< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > < a href = "https://www.npmjs.com/package/vue-socket.io-extended" target = "_blank" rel = "noopener" > socket.io client< / a > < / p >
< / li >
< li >
< p > < a href = "https://www.npmjs.com/package/vue-socket.io" > socket.io< / a > < / p >
< / li >
< / ul >
< / div >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_clientserver_site_iot_device" > 4.2. Client/Server site (IoT device)< / h3 >
< div class = "sect3" >
< h4 id = "_nodejs" > 4.2.1. Nodejs< / h4 >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications.
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > Almost no function in Node.js directly performs I/O, so the process never blocks. Thanks to this, scalable systems is very reasonable to be developed in Node.js.< / p >
< / div >
< div class = "paragraph" >
< p > < a href = "https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/" target = "_blank" rel = "noopener" > Overview of Blocking vs Non-Blocking< / a > < / p >
< / div >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
< strong > Node.js< / strong > is similar in design to, and influenced by, systems like < strong > Ruby’ s Event Machine< / strong > and < strong > Python’ s Twisted.< / strong >
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > Node.js takes the event model a bit further. It presents an < strong > event loop as a runtime construct< / strong > instead of a library.< / p >
< / div >
< div class = "paragraph" >
< p > < strong > In other systems, there is always a blocking call to start the event-loop.< / strong > < / p >
< / div >
< div class = "paragraph" >
< p > Typically,< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > behavior is defined through callbacks at the beginning of a script,< / p >
< / li >
< li >
< p > and at the end a server is started through a blocking call like < strong > EventMachine::run().< / strong > < / p >
< / li >
< / ul >
< / div >
< div class = "admonitionblock note" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-note" title = "Note" > < / i >
< / td >
< td class = "content" >
< div class = "paragraph" >
< p > In Node.js, there is no such start-the-event-loop call.< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > < strong > Node.js< / strong > simply < strong > enters the event loop after executing the input script.< / strong > < / p >
< / li >
< li >
< p > < strong > Node.js exits the event loop< / strong > when there are < strong > no more callbacks to perform.< / strong > < / p >
< / li >
< / ul >
< / div >
< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > Node.js being < strong > designed without threads< / strong > doesn’ t mean you can’ t take advantage of multiple cores in your environment.< / p >
< / div >
< div class = "paragraph" >
< p > Child processes can be spawned by using our < strong > child_process.fork() API,< / strong > and are designed to be easy to communicate with.< / p >
< / div >
< div class = "admonitionblock tip" >
< table >
< tr >
< td class = "icon" >
< i class = "fa icon-tip" title = "Tip" > < / i >
< / td >
< td class = "content" >
Built upon that same interface is the cluster module, which < strong > allows you to share sockets between processes< / strong > to enable load balancing over your cores.
< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_socket_io" > 4.2.2. socket.io< / h4 >
< div class = "paragraph" >
< p > < strong > Socket.IO< / strong > is a library that enables < strong > real-time< / strong > , < strong > bidirectional< / strong > and < strong > event-based< / strong > communication between the browser and the server.< / p >
< / div >
< div class = "paragraph" >
< p > It consists of:< / p >
< / div >
< div class = "ulist" >
< ul >
< li >
< p > a Node.js server: Source | API< / p >
< / li >
< li >
< p > a Javascript client library for the browser (which can be also run from Node.js): Source | API< / p >
< / li >
< / ul >
< / div >
< div class = "imageblock" >
< div class = "content" >
< img src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0gAAACDCAYAAAC3IDsxAAAgAElEQVR4Xu2dB7QUVdb9rzqOiTSDoiAiEpQRBUEw8BkHZUxg+lAwoIIoOgZM6DAqYgIVdcTAoCKIAXHGrCOIIiYMo6KMEWYMyCgGVMzZ//rd/3feupTVXdWvu9+r7rfPWr26u8KtW7uqu+6+55x9Vvj5559/djIhIASEgBAQAkJACAgBISAEhIAQcCuIIOkuEAJCQAgIASEgBISAEBACQkAI/H8ERJB0JwgBISAEhIAQEAJCQAgIASEgBP4PAREk3QpCQAgIASEgBISAEBACQkAICAERJN0DQkAICAEhIASEgBAQAkJACAiB5RGQB0l3hBAQAkJACAgBISAEhIAQEAJCQB4k3QNCQAgIASEgBISAEBACQkAICAF5kHQPCAEhIASEgBAQAkJACAgBISAEYhFQiJ1uDCEgBISAEBACQkAICAEhIASEwP8hIIKkW6FiEKCm8Y8//uh++ukn9/3337sffvjBff311+6rr77yLz5/8cUXNcts3TfffONeeeUV9/LLL7ujjjrKHXjggRVzzuqoEBACQkAICAEhIASEQN0ikIogMRidN2+e69+/v1tppZViXyuuuKJr3bq1e++99xyf2W6FFVbwn3nZ59/85jfu888/r2kj3Mba/tWvflWzPcv4bu/WNu/NmjXzg+HofvadbdZYYw3HANn6wPHsmPaZ90aNGvlBdriMz1i4bLXVVvPt2XK7XOG2LKPPDODNGNxj9h5+XnXVVf15sI7BP++5Xpwb1yPczj7HLWvcuLH79NNP/fbhi75BNuzFd170+8svv/TLbRuOZ99tO/vOeYDJ0qVLl2uLY7EN9t1339Wssz6wjr598sknfhvajet/HG5gYG2H14e+04bdc+G9wvb0Y99993U333xz3f7KdDQhIASEgBAQAkJACAiBikEgkSDNnTvXPf744+5vf/ubW7x4sR9kNm/e3L399ts1g95NN93ULViwwBOV9ddf35MkIyHt2rVzb731lv/OgJjBtw162ZZ1Zuuss4579913a8gB5AYyZcTByIHtv8oqq3hSYwNr+vXhhx/W7A9ho89GcFZeeWU/EGfgbAPrtdde2+/DMtplW0gcA3fbj22bNm3qPvvsM08gGGyzDoIG+QjJEmQBskN79MuM/ZctW+b3C41z/Pbbbz3pCa1Jkyb+eCGRon9rrrmm768tDwkE/aHfceSK49CebR8SxnXXXde9//77/vpFyQX40GZIQo2sgkXLli39ej7zAmNe9plrAqH89a9/vdyLa2ev1Vdf3W/Pd8gi7+DI5/Cdz+F+fI7imeuXN2PGDDd27Fh3yimnuN13371ifqDqqBAQAkJACAiB+kaAsdTUqVPd008/7Tp27Og6d+7sn9Hhc9q+2zKe2Tz77bltY6/6Phcdv+EiAOeAv2y//faJICQSpJ49e7oddtjBE4FRo0bVDGJtEMzANstm5MpIlHlMzMMRhm2FHpzQ22KkwsK7bDvOO+rxYcAeEiPDJur1CJezfUjG+Mz2RthCMsNyLCQyRkbNaxcSHftsXjnbJsvXrBx9mzVrljv11FNdq1at3L333luOQ6hNISAEhIAQEAJVh8AzzzzjidHs2bPdU0895ZjMZrKWCWcmd8MXk+j2gkgRfWTfGbeEhCmc8LTJUSZzGdPYZCvb8znX+1prreUn3m2S1iZnc33nODaGyhURFS6nnXC8lfQ5HKPFRSzZeK7qbpL/O6Fwgj4cD8dFT9kytgvX58Im3C4atRWN+MpFxm+66SZ3//33uxtvvDHxEiQSpJ133tltvPHG/gdw1VVXJTaoDYRAFhHgj/3EE090eMvuu+++LHZRfRICQkAICAEhkDkEGEwefvjhPvriySefdG3atHEQEwu5t3cihsj3DUP0LVTftmEs2bZtW/f666/XhPFbiL1NFocTutE0jWiKBISE/YigsaibKIDh4JtoHov8YbtoGL8N8I1EhRPjtn24TzRih/5wPmE7uT5zLuutt57773//W9PlcLKchdHJ8w022MC9+eaby51irkiaTp06uVdffdVvm4uA2HLG+eRp58POtoX4EjUWxSPa34022qhmu7g+2rK4c4r7EXB//ec//1luVfT60dYbb7xR42CIEie2J6Xm2WefdR06dMj7W0skSPvtt58POcMmTpyYuR+uOiQE0iDwyCOPuGOPPdbnyf3jH/9Is4u2EQJCQAgIASEgBP4vzeCdd95xAwYM8M/SXXfdtSy45CJXScvpDJ4qiw4yYhPmWluOMmH/cdtFl+G1spzsaB63tW8RQyHJi0Yghd/xYNFmtL0wlzzuc6689DDyifEN1yiOkJn3JfTahLncRm5yXVRSIUgfiZIgvofempAItWjRwn300UeJuf1GAvFKWnpLqF0QkuLocogx4lzhciPV1tcwCuvFF190RBTh2SQ9KJ8lEqQjjjjC33Sw4kmTJpXlB6FGhUC5ESCPbtiwYX62BveqTAgIASEgBISAEEiHAHnReDr22WcfH66+0047pdtRWwmBDCGAo2f48OFu0aJF3gtaFEEaMWKEb4hY0euvvz5Dp6muCIH0CBA3jcT3Vltt5SZMmJB+R20pBISAEBACQqCBI4DIFgJce+yxhxs9enSqJPcGDplOP4MIXHnllV6sC7EGPFxFEaQxY8b4pDxi9khukgmBSkSAJNNBgwb52GcU7WRCQAgIASEgBIRAOgQYA6J226dPH3fRRRe5Xr16pdtRWwmBDCFw2WWXuZEjR/o8JVSaiyJIzLbfcccdPg9p+vTpGTpNdUUIpEfg+eefd/vvv79r3769CFJ62LSlEBACQkAICAFfU5ISIzvuuKO7/PLL3RZbbCFUhEDFIXDxxRc7HD8IUhRNkKZNm+bV63BF3XbbbRUHhjosBEBg/vz5bq+99nIbbrihCJJuCSEgBISAEBACBSBAkj4F4Sm2zgCza9euBeytTYVANhC44IIL3DnnnOP+/e9/e7n6ojxIyCOPGzfO69Dfdddd2ThD9UIIFIgAswVIlCJ7qRC7AsHT5kJACAgBIdCgETCChOeIifNNNtmkQeOhk69MBM477zw3duxYt3DhwuIJEpr3gwcPdt27d1cOUmXeD+q1c77mAjW9IEkSadAtIQSEgBAQAkIgPQKE1qEAi+fonnvu8dEYMiFQaQggMILTpyQESTPvlXb51d84BCgutu2227rNNttMdZB0iwgBISAEhIAQKAABlIw///xzR/HPhx9+2AseyYRApSFwxhlnOAof4/wpOsRu8eLFrlu3bv71wAMPVBoW6q8Q8Agg6YjEd48ePdy9994rVISAEBACQkAICIGUCFjRVIjRP//5T9eqVauUe2ozIZAdBP70pz85pL4XLFhQPEFixgClh6233to99NBD2TlL9UQIFIAABe4QaWDGgPAAmRAQAkJACAgBIZAOgV/96lfu22+/9c/QV1991a255prpdtRWQiBDCJx88snu6quvLg1B4rxWWGEFXxRszpw5GTrNwrvy2GOP+TwUZkB69+7tXcXE0Xbu3Nmtt956hTeoPSoGgSVLlriNN97Yh9lJbKRiLps6KgSEgBAQAhlAYKWVVnLff/+9L/nyzjvvuCZNmmSgV+qCECgMAUQaqOP12muvFe9B4tAUCOvSpYubO3duYT3J2NbPPfec94TxI48aMuYk8A8cONCTKFl1IfDRRx+5Dh06+GKx48ePr66T09kIASEgBISAECgjAkyU//zzz2611VZzn3zyiVt11VXLeDQ1LQTKg8Dxxx/vpkyZ4oW7is5Boos0su666zoIRqXbsmXL3AcffODefPNN/yLHilhEEraYFcG22247r9jXunXrSj9d9f//EPj000/99YT8UvhYJgSEgBAQAkJACKRDwAiSeZJWXHHFdDtqKyGQIQSOPfZYLzJCylDRhWI5L0KTiD+l2Ga12COPPOLmzZvnhg8fXnNKJB7++c9/drNmzXIbbLCBJ01JAFYLHtV+Hl9++aWPmd51113d7bffXu2nq/MTAkJACAgBIVA
< / div >
< / div >
< div class = "paragraph" >
< p > < a href = "https://socket.io/" target = "_blank" rel = "noopener" > See more info here: Socket.io< / a > < / p >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_express" > 4.2.3. express< / h4 >
< div class = "paragraph" >
< p > Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.< / p >
< / div >
< div class = "paragraph" >
< p > < strong > Fast, unopinionated, minimalist web framework for Node.js< / strong > < / p >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_nosql" > 4.2.4. NoSQL< / h4 >
< div class = "paragraph" >
< p > A NoSQL (originally referring to "non-SQL" or "non-relational") database provides a mechanism for storage and retrieval of data that is modeled in means other than the tabular relations used in relational databases.< / p >
< / div >
< div class = "paragraph" >
< p > < a href = "https://www.mongodb.com/nosql-explained" > More info< / a > < / p >
< / div >
< div class = "paragraph" >
< p > MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud
-< / p >
< / div >
< div class = "paragraph" >
< p > < a href = "https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/" > Intro< / a > < / p >
< / div >
< div class = "paragraph" >
< p > < a href = "https://docs.mongodb.com/drivers/node/" > MongoDB and Nodejs < / a > < / p >
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "sect1" >
< h2 id = "_example_application" > 5. Example Application< / h2 >
< div class = "sectionbody" >
< div class = "sect2" >
< h3 id = "_client_site" > 5.1. Client site< / h3 >
< div class = "sect3" >
< h4 id = "_main_config" > 5.1.1. main (config)< / h4 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-javascript" data-lang = "javascript" > import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
import BootstrapVue from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import VueSweetalert2 from 'vue-sweetalert2';
Vue.use(VueSweetalert2);
import VueSocketIOExt from 'vue-socket.io-extended'; < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
import io from 'socket.io-client'; < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
const socket = io('http://localhost:8084', { < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
autoConnect: false
});
Vue.use(VueSocketIOExt, socket);
Vue.use(BootstrapVue);
Vue.config.productionTip = false
new Vue({
el: '#app',
store,
render: h => h(App)
})< / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > import socket package< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > import socket package< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > Connect to socket server< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_app_load" > 5.1.2. App (load)< / h4 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-html" data-lang = "html" > < template>
< div id="app">
< i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
...
< div>
< /template>
< script>
import DocLive from './components/DocLive.vue' < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
import "@/assets/css/themify-icons.css";
export default {
name: 'app',
components: {
},
data() {
return {
show: true,
SwarmabAsciiLabTemplate:''
}
},
mounted() {
},
methods: {
saveDocLive() {
this.$root.$emit('asciilive_save','save') < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
},
}
}
< /script>
< style>
< /style> < / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > your html< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > import module< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > Send Message to other components< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_create_compoment" > 5.1.3. Create compoment< / h4 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-html" data-lang = "html" > < template>
< div id="app">
< i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
...
< div class="row" >
< div :class="columnview"> < i class = "conum" data-value = "5" > < / i > < b > (5)< / b >
< run-llo
style="background-color: #f8f9fa"
>
< /run-llo>
< /div>
< div :class="columncode"> < i class = "conum" data-value = "5" > < / i > < b > (5)< / b >
< ad-hoc
style="background-color: #f8f9fa"
>
< /ad-hoc>
< /div>
< /div>
< div>
< /template>
< script>
import RunLlo from "./doclive/runLlo.vue"; < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
import AdHoc from "./doclive/AdhocView.vue";
export default {
name: 'DocLive', < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
props: {
},
components: {
RunLlo, < i class = "conum" data-value = "4" > < / i > < b > (4)< / b >
AdHoc < i class = "conum" data-value = "4" > < / i > < b > (4)< / b >
},
data () {
return {
loading: false,
showhistory : 0,
productIndex: 1,
showmenou: 1,
columnviewdefault : 0,
columncodedefault : 0,
columnview : 'col-7 order-first',
columncode : 'col-5 order-last',
tutorMenou: 'student'
}
},
created: function () {
},
mounted() {
this.$root.$on('LLOshowmenounotebooks', () => {
this.showmenou = 1
}),
this.$root.$on('lloshowchallengehistory', (llo,active) => {
this.showhistory = 1
})
},
beforeDestroy () {
this.$root.$off('LLOshowmenounotebooks'),
this.$root.$off('lloshowchallengehistory') // working
},
methods: { < i class = "conum" data-value = "6" > < / i > < b > (6)< / b >
fullscreen(action){ < i class = "conum" data-value = "7" > < / i > < b > (7)< / b >
if(action == 'max'){
this.columnview = 'col-11 order-first'
this.columncode = 'col-1 order-last'
this.columnviewdefault = 1
this.columncodedefault = 0
//set height iframe
this.$root.$emit('LLOresizemenounotebooks','max')
console.log(this.columnview)
}
else if(action == 'min'){
this.columnview = 'col-7 order-first'
this.columncode = 'col-5 order-last'
this.columnviewdefault = 0
this.columncodedefault = 1
//set height iframe
this.$root.$emit('LLOresizemenounotebooks','min')
console.log(this.columnview)
}
else if(action == 'codemax'){
this.columnview = 'col-1 order-first'
this.columncode = 'col-11 order-last'
this.columnviewdefault = 0
this.columncodedefault = 1
console.log(this.columnview)
}
else if(action == 'codemin'){
this.columnview = 'col-7 order-first'
this.columncode = 'col-5 order-last'
this.columnviewdefault = 1
this.columncodedefault = 0
this.$root.$emit('LLOresizemenounotebooks','min')
console.log(this.columnview)
}
},
async onAction (action) { < i class = "conum" data-value = "8" > < / i > < b > (8)< / b >
this.tutorMenou='tutor'
//this.tutorMenou='student'
}
}
}
< /script>
< style>
< /style> < / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > your html< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > import your components help files< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > Export your component< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "4" > < / i > < b > 4< / b > < / td >
< td > your component files< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "5" > < / i > < b > 5< / b > < / td >
< td > insert your component< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "6" > < / i > < b > 6< / b > < / td >
< td > your methods< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "7" > < / i > < b > 7< / b > < / td >
< td > method to controll window behavior< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "8" > < / i > < b > 8< / b > < / td >
< td > on action< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_use_your_component" > 5.1.4. Use your component< / h4 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-html" data-lang = "html" > < template>
< div>
< !-- menou -->
< div class="row"
v-show="showmenou == 1"
>
...
< /div>
< !-- menou -->
< div class="row" >
< div :class="columnview">
< run-llo < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
style="background-color: #f8f9fa"
>
< /run-llo>
< /div>
< div :class="columncode">
< ad-hoc < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
style="background-color: #f8f9fa"
>
< /ad-hoc>
< /div>
< /div>
< /div>
< /template>
< script>
import RunLlo from "./doclive/runLlo.vue"; < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
import AdHoc from "./doclive/AdhocView.vue"; < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
export default {
props: {
},
components: {
RunLlo, < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
AdHoc < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
},
data () {
return {
loading: false,
showhistory : 0,
productIndex: 1,
showmenou: 1,
columnviewdefault : 0,
columncodedefault : 0,
columnview : 'col-7 order-first',
columncode : 'col-5 order-last',
tutorMenou: 'student'
}
},
created: function () {
},
mounted() {
this.$root.$on('LLOshowmenounotebooks', () => {
this.showmenou = 1
}),
this.$root.$on('lloshowchallengehistory', (llo,active) => {
this.showhistory = 1
})
},
beforeDestroy () {
this.$root.$off('LLOshowmenounotebooks'),
this.$root.$off('lloshowchallengehistory') // working
},
methods: {
...
}
}
< /script>
< !-- Add "scoped" attribute to limit CSS to this component only -->
< style scoped>
< /style> < / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > use component< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > import components< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_sockets" > 5.1.5. Sockets< / h4 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-html" data-lang = "html" > < template>
< div>
...
< /div>
< /template>
< script>
import Vue from 'vue' < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
import JSZip from 'jszip'; < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
import FileSaver from 'file-saver'; < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
export default {
components: {
},
data () {
return {
showlloedit:true,
issocket:'close',
socketdata:'',
code:[],
iotdata: [ < i class = "conum" data-value = "4" > < / i > < b > (4)< / b >
{
"iot1": {
"id": 1,
"name": "auto1",
"img": "rinse.png",
"Servicios": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
]
},
},{
"iot2": {
"id": 2,
"name": "auto2",
"img": "shirt-2.png",
"Servicios": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
]
},
},{
"iot3": {
"id": 3,
"name": "auto3",
"img": "iron.png",
"Servicios": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
]
},
},{
"iot4": {
"id": 4,
"name": "auto4",
"img": "wring.png",
"Servicios": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
]
}
}
]
}
},
methods: {
async addiot() {
console.log(JSON.stringify(this.iotdata))
},
async socketopen () {
this.$socket.client.open(); < i class = "conum" data-value = "5" > < / i > < b > (5)< / b >
},
/**
*
* == socketclose()
*
* [source,javascript]
* ----
* this.$socket.client.close();
* ----
*
*/
async socketclose () { < i class = "conum" data-value = "6" > < / i > < b > (6)< / b >
this.$socket.client.close();
}
},
computed: {
},
/**
*
* == Socket subscribe
*
* [source,javascript]
* ----
* this.$root.$on('iot_add', (v) => { < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
* ...
* })
* sdfsf
den to perni sdfsf
* ----
* < 1> EventBus is used for parent/child component communication.
*
*/
mounted() {
this.$root.$on('iot_add', (v) => {
this.iotdata.push(v);
//this.iotdata = v
this.addiot()
this.$socket.client.emit('subscribe', 'iot');
})
this.$root.$on('socket_add', (v) => {
this.socketdata = v;
console.log('socket_add ' + JSON.stringify(v))
this.$socket.client.emit('log', this.socketdata);
})
},
/**
*
* == Destroy EventBus
*
* See
* https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle[Vue.js Lifecycle Hooks^].
*
* *beforeDestroy*
*
* - beforeDestroy is fired right before teardown. Your component will still be fully present and functional.
*
* [source,javascript]
* ----
* this.$root.$off('iot_add') < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
* ----
* < 1> EventBus is used for parent/child component communication.
*
*/
beforeDestroy () {
this.$root.$off('iot_add')
this.$root.$off('socket_add')
},
/**
*
* == Open a socket
*
* See
* https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle[ Vue.js Lifecycle Hooks^]
*
* *Created*
*
* - You are able to access reactive data and events that are active with the created hook. Templates and Virtual DOM have not yet been mounted or rendered:
*
* [source,javascript]
* ----
* this.socketopen()
* ----
*
*/
created () {
this.socketopen()
},
/**
*
* == Socket events
*
* [source,javascript]
* ----
* this.$socket.client.emit('authenticate', 'logintoken');
* ----
*
*/
sockets: {
connect() {
this.$socket.client.emit('authenticate', 'logintoken');
this.$socket.client.emit('socket_id_get', 'socketdatasend');
console.log('socket connected '+ 'socketdatasend' )
this.issocket = 'open'
},
/**
*
* === onError
*
*/
error(error) {
console.log("socket error "+JSON.stringify(error))
this.issocket = 'close'
},
/**
*
* === connect_error
*
*/
connect_error(error) {
console.log("socket connect_error "+JSON.stringify(error))
this.issocket = 'close'
},
/**
*
* === connect_error
*
*/
disconnect(reason) {
console.log("socket disconnect "+JSON.stringify(reason))
this.issocket = 'close'
},
/**
*
* === Socket connect_timeout
*
*/
connect_timeout(reason) {
console.log("socket timeout "+JSON.stringify(reason))
this.issocket = 'close'
},
/**
*
* === Socket reconnect
*
*/
reconnect(attemptNumber) {
console.log("socket reconnect attemptNumber "+JSON.stringify(attemptNumber))
},
/**
*
* === connect_attempt
*
*/
reconnect_attempt(attemptNumber) {
console.log("socket reconnect_attempt "+JSON.stringify(attemptNumber))
},
/**
*
* === Socket reconnecting
*
*/
reconnecting(attemptNumber) {
console.log("socket reconnecting "+JSON.stringify(attemptNumber))
},
/**
*
* === reconnect_error
*
*/
reconnect_error(error) {
console.log("socket reconnect_error "+JSON.stringify(error))
this.issocket = 'close'
},
/**
*
* === unauthorized
*
*/
unauthorized(val) {
console.log("socket unauthorized "+JSON.stringify(val))
this.issocket = 'close'
},
/**
*
* === connected
*
*/
socket_id_emit(val) {
console.log("socket id from server "+JSON.stringify(val))
console.log("socket id from serveri saved "+JSON.stringify(socketsave))
this.issocket = 'open'
},
/**
*
* === Socket onMessage
*
*/
async adhocEmit(val) {
console.log("socket from server "+JSON.stringify(val))
this.issocket = 'open'
this.$wait.start('myRunInstance1');
// render begin
this.tryLLO = 'on'
if(this.firstbootstrap === 0 ){
await this.bootsrapllo();
this.firstbootstrap = 1
}
var output = log.data.out
var mydinfunction = `
< div class="row">
< b-col class="" cols="12" sm="12" md="12" >
${output}
< /b-col>
< /div> `
try {
let divascii = document.createElement('div');
divascii.setAttribute("class", "container-fluid w-100 p-3 llotry")
divascii.innerHTML = mydinfunction
this.addtask(divascii);
}catch (ex) {
console.log(" logi error1 "+JSON.stringify(ex))
return
}
this.$wait.end('myRunInstance1');
},
async iotdata(val) {
console.log(" socket from iotdata "+JSON.stringify(val))
},
async message(val) {
console.log(" socket message "+JSON.stringify(val))
}
}
};
< /script>
< style>
.CodeMirror {
font-family: monospace;
height: 750px;
}
< /style> < / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > import module< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > import module< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > import module< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "4" > < / i > < b > 4< / b > < / td >
< td > json examples coming from IoT device< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "5" > < / i > < b > 5< / b > < / td >
< td > open socket< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "6" > < / i > < b > 6< / b > < / td >
< td > close socket< / td >
< / tr >
< / table >
< / div >
< div class = "paragraph" >
< p > See also See < a href = "https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle" target = "_blank" rel = "noopener" > Vue.js Lifecycle Hooks< / a > < / p >
< / div >
< / div >
< div class = "sect3" >
< h4 id = "_create_store" > 5.1.6. create store< / h4 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-javascript" data-lang = "javascript" > import { mapState, mapActions, commit } from 'vuex' < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
import store from '@/store/index'
import axios from 'axios' < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
export default {
namespaced: true, < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
state: { < i class = "conum" data-value = "4" > < / i > < b > (4)< / b >
llo: {},
socketid:''
},
getters: { < i class = "conum" data-value = "5" > < / i > < b > (5)< / b >
getllosrc (state, container) {
//console.log("js1 get "+JSON.stringify(state.llo))
return state.llo
},
getsocketid (state, container) {
//console.log("js1 get "+JSON.stringify(state.llo))
return state.socketid
}
},
mutations: { < i class = "conum" data-value = "6" > < / i > < b > (6)< / b >
setllo (state, data) {
//console.log("js1 set "+JSON.stringify(data))
state.llo=data;
},
setsocketid (state, data) {
//console.log("js1 set "+JSON.stringify(data))
state.socketid = data;
}
},
actions: { < i class = "conum" data-value = "7" > < / i > < b > (7)< / b >
async get_data({commit,rootGetters}, value) {
try {
let p = await axios.get("http://localhost:8084/run", { < i class = "conum" data-value = "8" > < / i > < b > (8)< / b >
timeout: 45000,
params: {
code: value.code
}
});
//var p = value.code
console.log("paramp "+JSON.stringify(p))
store.dispatch('pipelineLLO/setScriptllo', p)
return p;
} catch (e) {
if(e.error == "invalid_token"){
window.location.href = 'https://api-login.swarmlab.io:8089';
}else{
var R = {
ERROR_str: e,
ERROR: 'yes'
}
return R;
}
}
},
setScriptllo({commit}, value) {
//console.log("container "+value)
commit('setllo', value)
},
setsocketllo({commit}, value) {
//console.log("container "+value)
commit('setsocketid', value)
},
setScriptCodlogAction({commit}, value) {
//console.log("container "+value)
commit('setScriptCodelog', value)
}
}
}< / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > import vuex < a href = "https://vuex.vuejs.org/" > More info< / a > < / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > import axios< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > enable namespace< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "4" > < / i > < b > 4< / b > < / td >
< td > create state (store)< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "5" > < / i > < b > 5< / b > < / td >
< td > getters< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "6" > < / i > < b > 6< / b > < / td >
< td > setters< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "7" > < / i > < b > 7< / b > < / td >
< td > actions sync/async< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "8" > < / i > < b > 8< / b > < / td >
< td > Rest call< / td >
< / tr >
< / table >
< / div >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_server_site" > 5.2. Server site< / h3 >
< div class = "listingblock javascript" >
< div class = "content" >
< pre class = "highlight" > < code > var path = require('path'); < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
var app = require('express')(); < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
var http = require('http').Server(app); < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
var io = require('socket.io')(http); < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
const socketAuth = require('socketio-auth'); < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
const cors = require('cors') < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
const whitelist = [
'http://localhost:3080',
'http://localhost:3081',
'http://localhost:3082'
]
const corsOptions = {
credentials: true,
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
allowedHeaders: [
'Content-Type',
'Authorization',
'X-Requested-With',
'device-remember-token',
'Access-Control-Allow-Origin',
'Access-Control-Allow-Headers',
'Origin',
'Accept'
],
origin: function(origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(null, true)
}
}
}
app.get('/run', [ // < i class = "conum" data-value = "3" > < / i > < b > (3)< / b >
//check('access_token').isLength({ min: 40 }),
//check('llo').isBase64()
],
cors(corsOptions), (req, res, next) => { < i class = "conum" data-value = "4" > < / i > < b > (4)< / b >
var RES = new Object();
RES.code = req.query["code"] < i class = "conum" data-value = "5" > < / i > < b > (5)< / b >
console.error('socket get from client' + RES.code);
RES.error = false
RES.error_msg = "ok"
io.emit("iotdata", RES) < i class = "conum" data-value = "6" > < / i > < b > (6)< / b >
io.in('iot').emit('message', RES); < i class = "conum" data-value = "7" > < / i > < b > (7)< / b >
res.json(RES)
});
app.post('/run', [ < i class = "conum" data-value = "8" > < / i > < b > (8)< / b >
//check('access_token').isLength({ min: 40 }),
//check('llo').isBase64()
],
cors(corsOptions), (req, res, next) => {
console.error('socket post from client');
io.emit("customEmit", 'data')
var RES = new Object();
RES.error = false
RES.error_msg = "ok"
res.json(RES)
});
io.on('connection', s => { < i class = "conum" data-value = "9" > < / i > < b > (9)< / b >
console.error('socket connection');
var id = s.id
s.on('pingServerEmit', obj => {
console.error('socket.io pingServer');
var data = obj+' testserver'
io.emit("customEmit", data)
io.in('iot').emit('message', data);
console.error('from client '+ s.id + ' obj ' + obj);
});
s.on('subscribe', function(room) { < i class = "conum" data-value = "10" > < / i > < b > (10)< / b >
console.log('joining room', room);
s.join(room);
})
io.on('unsubscribe', function(room) {
console.log('leaving room', room);
io.leave(room);
})
// when the client emits 'new message', this listens and executes
s.on('log', (data, room) => {
s.to('iot').emit('message', data);
console.log('broadcast', data);
});
});
http.listen(8084, () => console.error('listening on http://localhost:8084/'));
console.error('socket.io example');< / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > load modules< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > config cors < a href = "https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target = "_blank" rel = "noopener" > More info< / a > < / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "3" > < / i > < b > 3< / b > < / td >
< td > create Get< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "4" > < / i > < b > 4< / b > < / td >
< td > use cors< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "5" > < / i > < b > 5< / b > < / td >
< td > get data< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "6" > < / i > < b > 6< / b > < / td >
< td > send with socket to all< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "7" > < / i > < b > 7< / b > < / td >
< td > send with socket to room< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "8" > < / i > < b > 8< / b > < / td >
< td > post< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "9" > < / i > < b > 9< / b > < / td >
< td > handle socket connections< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "10" > < / i > < b > 10< / b > < / td >
< td > subscribe< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "sect2" >
< h3 id = "_iot_device" > 5.3. IoT Device< / h3 >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" > < code class = "language-javascript" data-lang = "javascript" > var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
const socketAuth = require('socketio-auth');
const axios = require('axios');
axios.defaults.timeout = 30000
const helmet = require('helmet');
const cors = require('cors')
const whitelist = [
'http://localhost:3080',
'http://localhost:3081',
'http://localhost:3082'
]
const corsOptions = {
credentials: true,
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
allowedHeaders: [
'Content-Type',
'Authorization',
'X-Requested-With',
'device-remember-token',
'Access-Control-Allow-Origin',
'Access-Control-Allow-Headers',
'Origin',
'Accept'
],
origin: function(origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(null, true)
//callback(new Error('Not allowed by CORS'))
}
}
}
app.use(helmet());
app.get('/run', [
//check('access_token').isLength({ min: 40 }),
//check('llo').isBase64()
],
cors(corsOptions), (req, res, next) => {
var RES = new Object();
RES.tmp_token = req.query["access_token"]
RES.datafile = req.query["datafile"]
RES.service = req.query["service"]
RES.action = req.query["action"]
RES.error = false
RES.error_msg = "ok"
res.json(RES)
});
app.post('/run', [
//check('access_token').isLength({ min: 40 }),
//check('llo').isBase64()
],
cors(corsOptions), (req, res, next) => {
console.error('socket post');
io.emit("customEmit", 'data')
var RES = new Object();
RES.error = false
RES.error_msg = "ok"
res.json(RES)
});
socketoptions = {
secure:true,
reconnect: true,
rejectUnauthorized : false
};
// Client
var io2 = require('socket.io-client');
var socket = io2.connect('http://localhost:8084', socketoptions);
var global = {}
socket.on('connection', s => {
console.log(s)
console.error('socket2 connection');
global.id = s.id
s.emit('log', 'client');
});
var roomiot = 'iot'
socket.emit('subscribe', roomiot); < i class = "conum" data-value = "1" > < / i > < b > (1)< / b >
socket.emit('log', 'client1');
socket.on('message', function (data) { < i class = "conum" data-value = "2" > < / i > < b > (2)< / b >
//console.log('from room ' + data);
console.log("from room iot "+JSON.stringify(data))
//io.emit("customEmit", data)
});
io.on('connection', s => {
console.error('socket connection');
var roomiot = 'iot'
var id = s.id
s.on('pingServer', obj => {
console.error('socket.io pingServer');
//console.error(s);
console.error('fromclient '+obj);
var data = obj+' testfromclient '+id
socket.emit("pingServerEmit", data)
socket.emit('send', { room: roomiot, message: 'message iot' });
});
s.on('customEmit', obj => {
var data = obj+' test customeEdit '+id
//console.error('from server ' + data);
//s.emit("pingServerEmit", data)
socket.emit("customEmit", data)
});
});
http.listen(3081, () => console.error('listening on http://localhost:3081/'));
console.error('socket.io example');< / code > < / pre >
< / div >
< / div >
< div class = "colist arabic" >
< table >
< tr >
< td > < i class = "conum" data-value = "1" > < / i > < b > 1< / b > < / td >
< td > subscribe< / td >
< / tr >
< tr >
< td > < i class = "conum" data-value = "2" > < / i > < b > 2< / b > < / td >
< td > event on message< / td >
< / tr >
< / table >
< / div >
< / div >
< / div >
< / div >
< / div >
< div id = "footer" >
< div id = "footer-text" >
Last updated 2020-10-28 18:59:27 UTC
< / div >
< / div >
< / body >
< / html >