/m2m-quicktour

A quick start-up guide on how to develop applications using the node.js m2m library.

Primary LanguageJavaScriptMIT LicenseMIT

Quick Tour

  1. M2M Publish-Subscribe Pattern
  2. M2M Client-Server Pattern
  3. M2M Browser Client
  4. Edge Computing Using Local Area Networking
  5. Create an Edge Gateway
  6. Create an M2M Bridge Gateway
  7. Create a Server Load Balancer for Edge Computing
  8. Edge C/C++ Connector Application
  9. Edge C# Connector Application
  10. M2M Server-To-Server Communication
  11. Edge Raspberry Pi GPIO Access



Publish-Subscribe Pattern

Before you start,  ensure you have a node.js installation in all of your remote endpoints.

Create an account and register your server endpoints.

Install m2m on your endpoints.

$ npm install m2m

Server 1

1. Choose any connect api below and save the code as server.js in your server 1 project directory.

Connect using callback

const m2m = require('m2m');

let server = new m2m.Server(100);

server.connect(() => {
  // server resources 
  server.publish('random-number', (ws) => {
    let rn = Math.floor(Math.random() * 100);
    let data = {id:ws.id, topic:ws.topic, value:rn};
    ws.send(data);
  });
});

Connect using async/await

const m2m = require('m2m');

let server = new m2m.Server(100);

let main = async () => {
  await server.connect();
  // add server resources here
}

main();

Connect using promise

const m2m = require('m2m');

let server = new m2m.Server(100);

m2m.connect()
.then(console.log) // success
.then(() => {
  // add server resources here
})  
.catch(console.log)

2. Start server 1 application.

$ node server.js

The first time you run your application,  it will ask for your userid and password credentials.

? Enter your userid (email):
? Enter your password:

The next time you run your application,  it will start automatically using a saved user token.

At anytime,  if you're having difficulty or issues restarting your application,  you can re-authenticate with an -r flag. This will refresh your token as shown below.

$ node server.js -r

Server 2

1. Save the code below as server.js in your server 2 project directory.

const m2m = require('m2m');

let server = new m2m.Server(200);

let main = async () => {
  let result = await server.connect();
  console.log(result); // success

  server.pub('random-number', (ws) => {
    let rn = Math.floor(Math.random() * 100);
    ws.send({id:ws.id, topic:ws.topic, value:rn});
  });
}

main();

2. Start server 2 application.

$ node server.js

Client

1. Save the code below as client.js in your client project directory.

Method 1:   Access each server using the access method

const m2m = require('m2m');

let client = new m2m.Client();

client.connect()
.then(console.log) // success
.then(() => {
  let client1 = client.access(100);
  let client2 = client.access(200);

  // using the default 5 secs polling interval
  client1.subscribe('random-number', (data) => {
    console.log('client1 subscribe random-number', data);
  });
  
  // using a polling interval of 10 secs 
  client2.sub('random-number', 10000, (data) => {
    console.log('client2 subscribe random-number', data);
  });

  setTimeout(() => {
    client1.unsubscribe('random-number');
    console.log('client1 unsub');
  }, 30000);

  setTimeout(async () => {
    // confirm unsubscribe if successful
    let result = await client2.unsub('random-number');
    console.log('client2 unsub', result); // true if successful
  }, 60000);
})
.catch(console.log)

Method 2:   Access each server directly from the client object by providing the server id

const { Client } = require('m2m');

let client = new Client();

client.connect()
.then(console.log) // success
.then(() => {

  // using the default 5 secs polling interval
  client.subscribe(100, 'random-number', (data) => {
  // or
  //client.subscribe({id:100, topic:'random-number'}, (data) => {
    console.log('client1 subscribe random-number', data);
  });
  
  // using a polling interval of 10 secs 
  client.sub(200, 'random-number', 10000, (data) => {
  // or
  //client.sub({id:200, topic:'random-number', interval:10000}, (data) => {
    console.log('client2 subscribe random-number', data);
  });

  setTimeout(() => {
    client.unsubscribe(100, 'random-number');
    console.log('client1 unsub');
  }, 30000);

  setTimeout(async () => {
    // confirm unsubscribe if successful
    let result = await client.unsub({id:200, topic:'random-number'});
    console.log('client2 unsub', result); // true if successful
  }, 60000);
})
.catch(console.log)

3. Start client application.

$ node client.js

You should get a similar output result as shown below.

client1 subscribe random-number { id: 100, topic: 'random-number', value: 18 }
client1 subscribe random-number { id: 100, topic: 'random-number', value: 8 }
client2 subscribe random-number { id: 200, topic: 'random-number', value: 98 }
client1 subscribe random-number { id: 100, topic: 'random-number', value: 96 }
client1 unsub
client2 subscribe random-number { id: 200, topic: 'random-number', value: 34 }
client1 subscribe random-number { id: 100, topic: 'random-number', value: 15 }
client2 unsub true

Client-Server Pattern

Server 1

1. Save the code below as server.js in your server 1 project directory.

const { Server } = require('m2m');

let server = new Server(100);

server.connect(() => {
  // server 1 available resources

  // publish resource
  server.publish('random-number', (ws) => {
    let rn = Math.floor(Math.random() * 100);
    ws.send({id:ws.id, topic:ws.topic, value:rn});
  });

  // common read/write resource 
  server.dataSource('/machine-1', (ws) => {
    let data = { id:ws.id, rootTopic:ws.rootTopic, subTopic:ws.subTopic }

    if(ws.topic === '/machine-1/sensor-1'){
      let rn = Math.floor(Math.random() * 200);
      data.type = 'sensor-1';
      data.value = rn; 
    }
    else if(ws.topic === '/machine-1/sensor-2'){
      let rn = Math.floor(Math.random() * 400);
      data.type = 'sensor-2';
      data.value = rn; 
    }
    else if(ws.topic === '/machine-1' && ws.payload){
      data.type = ws.payload.type;
      data.value = ws.payload.value;
    }  
    ws.send(data);
  });
});

2. Start server 1 application.

$ node server.js

Server 2

1. Save the code below as server.js in your server 2 project directory.

const { Server } = require('m2m');

let server = new Server(200);

server.connect(() => {
  // server 2 available resources

  // publish resource
  server.pub('random-number', (ws) => {
    let rn = Math.floor(Math.random() * 100);
    ws.send({id:ws.id, topic:ws.topic, value:rn});
  });

  // http get resource 
  server.get('/update-server-data/:id/new-data/:data', (req, res) => {
    res.send({id:res.id, query:req.query, params:req.params});
  });

  // http get resource
  server.get('/device-state', (req, res) => {
    res.send({id:res.id, path:res.path, query:req.query, params:req.params, state:'off'});
  });

  // http post resource 
  server.post('/machine-control/:id/actuator/:number/action/:state', (req, res) => {
    res.send({id:res.id, path:res.path, query:req.query, params:req.params});
  });    
});

2. Start server 2 application.

$ node server.js

Client

1. Save any of the code below as client.js in your client project directory.

Method 1

const m2m = require('m2m');

let client = new m2m.Client();

const main = async () => {
  let result = await client.connect();
  console.log(result);

  let c1 = client.access(100);
  let c2 = client.access(200);

  let s1 = await c1.read('/machine-1/sensor-1')
  console.log(s1)

  let s2 = await c1.read('/machine-1/sensor-2')
  console.log(s2)

  let s3 = await c1.write('/machine-1', {type:'root topic', value:350})
  console.log(s3)

  let gr = await c2.get('/update-server-data/320/new-data/'+JSON.stringify({pet:'cat', name:'Captain'})+'?name=Rv')
  console.log(gr)

  let pr = await c2.post('/machine-control/150/actuator/5/action/on?name=Ed', {id:200, state:'true'})
  console.log(pr)
}

main();

Method 2

const m2m = require('m2m');

let client = new m2m.Client();

client.connect()
.then(console.log) // success
.then(() => {

  client.read(100, '/machine-1/sensor-1')
  .then(console.log)

  client.read(100, '/machine-1/sensor-2')
  .then(console.log)

  client.write(100, '/machine-1', {type:'root topic', value:350})
  .then(console.log)

  client.get(200, '/update-server-data/320/new-data/'+JSON.stringify({pet:'cat', name:'Captain'})+'?name=Rv')
  .then(console.log)
  
  client.post(200, '/machine-control/150/actuator/5/action/on?name=Ed', {id:200, state:'true'})
  .then(console.log)

})
.catch(console.log)

3. Start client application.

$ node client.js

You should get an output result as shown below.

{ id: 100, subTopic: '/sensor-1', type: 'sensor-1', value: 126 }
{ id: 100, subTopic: '/sensor-2', type: 'sensor-2', value: 373 }
{
  id: 100,
  rootTopic: '/machine-1',
  subTopic: '',
  type: 'root topic',
  value: 350
}
{
  id: 200,
  query: { name: 'Rv' },
  params: { id: '320', data: '{"pet":"cat","name":"Captain"}' }
}
{
  id: 200,
  path: '/machine-control/150/actuator/5/action/on?name=Ed',
  query: { name: 'Ed' },
  params: { id: '150', number: '5', state: 'on' },
  body: { id: 200, state: 'true' }
}

Using A Browser Client


Using the client-server example,  we will use a browser client to access the available resources from the remote servers.

Browser Client Setup

1. Login to node-m2m and create a web access token.

From the manage security section in the main menu under the user account tab,  generate a web access token.

2. Install m2m in your web server.

$ npm install m2m

From node_modules/m2m/dist directory,  copy node-m2m.min.js file into your web server's public javascript directory.

3. Create a client instance from the global NodeM2M object.

<script src="/javascripts/node-m2m.min.js"></script>

<script> 

const { createClient } = NodeM2M(); 

let client = createClient();        

// web access token
let tkn = 'fce454138116159a6ad9a4234e71de810a1087fa9e7fbfda74503d9f52616fc5';

client.connect({server:'https://www.node-m2m.com', accessTkn:tkn}) 
.then(console.log) // success
.then(async () => {   

   client.read(100, '/machine-1/sensor-1')
  .then(console.log)

  client.read(100, '/machine-1/sensor-2')
  .then(console.log)

  client.write(100, '/machine-1', {type:'root topic', value:350})
  .then(console.log)

  client.get(200, '/update-server-data/320/new-data/'+JSON.stringify({pet:'cat', name:'Captain'})+'?name=Rv')
  .then(console.log)
  
  client.post(200, '/machine-control/150/actuator/5/action/on?name=Ed', {id:200, state:'true'})
  .then(console.log)

})
.catch(console.log)

</script>

You should get a similar result as shown below.

success
{ id: 100, subTopic: '/sensor-1', type: 'sensor-1', value: 22 }
{ id: 100, subTopic: '/sensor-2', type: 'sensor-2', value: 29 }
{
  id: 100,
  rootTopic: '/machine-1',
  subTopic: '',
  type: 'root topic',
  value: 350
}
{
  id: 200,
  query: { name: 'Rv' },
  params: { id: '320', data: '{"pet":"cat","name":"Captain"}' }
}
{
  id: 200,
  path: '/machine-control/m120/actuator/25/action/on?name=Ed',
  query: { name: 'Ed' },
  params: { id: '150', number: '5', state: 'on' },
  body: { id: 200, state: 'true' }
}