- M2M Publish-Subscribe Pattern
- M2M Client-Server Pattern
- M2M Browser Client
- Edge Computing Using Local Area Networking
- Create an Edge Gateway
- Create an M2M Bridge Gateway
- Create a Server Load Balancer for Edge Computing
- Edge C/C++ Connector Application
- Edge C# Connector Application
- M2M Server-To-Server Communication
- Edge Raspberry Pi GPIO Access
Before you start, ensure you have a node.js installation in all of your remote endpoints.
Create an account and register your server endpoints.
$ npm install m2m
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)
$ 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
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();
$ node server.js
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)
$ 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
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);
});
});
$ node server.js
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});
});
});
$ node server.js
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)
$ 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 the client-server example, we will use a browser client to access the available resources from the remote servers.
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.
$ npm install m2m
From node_modules/m2m/dist
directory, copy node-m2m.min.js
file into your web server's public javascript directory.
<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' }
}