본 Radar(레이더)는 동국대학교 TEstBEd에서 제공해준 (주)탑엔지니어링, SMART Radar Sensor 입니다.
RADAR의 역할은 하나의 TAS, 일종의 액추에이터 기능으로 사용하였습니다. 따라서 간단한 서버가 필요합니다. 해당 소스코드는 제 개인 깃허브에 업로드 해두었습니다. 그럼 먼저 소스코드에 대한 설명을 하겠습니다. 😁
RADAR(레이더)에서 송신하는 데이터를 받아줄 SERVER(서버)를 만들어 줍니다. 이때 RADAR(레이더)는 CLIENT(클라이언트) 역할을 수행합니다.
tas_radar로 tas_sample 디렉토리안에 새롭게 생성해주었습니다. tas_radar는 아래와 같은 package.json으로 구성되있으니 참고하시면 되겠습니다.
{
"name": "tas-radar",
"version": "1.0.0",
"description": "tas-radar",
"engines": {
"node": "10.15.0",
"npm": "6.9.0"
},
"scripts": {
"start": "nodemon index.js"
},
"author": "Seunghwan Lee",
"license": "ISC",
"dependencies": {
"dotenv": "^8.2.0",
"ip": "^1.1.5",
"mysql": "^2.18.1"
}
}
tas_radar
└───node_modules
│ .env
│ index.js
│ data_parse.js
│ package.json
│ package-lock.json
기능 구현을 위해서 간단하게 두개의 함수를 만들었습니다. tasReady와 tasHandler인데, tasReady에서 레이더에서 송신하는 데이터를 받고, 수신된 데이터가 있는 경우에 tasHandler가 작동됩니다. 코드는 다음과 같습니다.
레이더가 송신할 포트는 겹치지만 않도록 설정해주시면 됩니다. 앞서 thyme에서 tasport가 3105로 설정이 되어있기 때문에 .env 파일은 아래와 같이 설정하였습니다.
RS_PORT=3333
ST_PORT=3105
index.js 와 같은 디렉토리에 저장해주시면 되고, 저는 3333으로 포트를 설정해주었습니다. 😁
const tasReady = () => {
if (_server === null) {
// create server
_server = new net.createServer((socket) => {
console.log('[ socket connected ]');
// ...
})
_server.listen(process.env.RS_PORT, () => console.info('TCP SERVER listening on :' + ip.address() + ":" + port.toString()));
}
}
_server
라는 전역변수가 있으며 null 값으로 초기화가 되어있습니다. net.createServer
를 통해서 서버 객체를 생성해주고 listen
을 통해 접속하려는 클라이언트가 설정된 포트(port)로 접속할 수 있도록 동작을 시킵니다. net.createServer
함수 안에는 callback 함수가 있어서 클라이언트가 요청을 하면 callback 함수가 작동됩니다.
callback 함수를 이용하여 다양한 기능을 구현할 수 있습니다. 이번에는 가장 기본적인 4개를 이용하여 구현을 해보았습니다.
...
// to thyme
var net = require('net');
var asClient = net.connect({ port: process.env.ST_PORT });
// socket encoding
socket.setEncoding('hex');
// data
socket.on('data', (data) => tasHandler(data, asClient));
// end
socket.on('end', (data) => console.log('[ socket end with data : ' + data + ']'));
// close
socket.on('close', (hasErr) => hasErr ? console.error('[ socket closed with error ]') : console.info('[ socket closed ]'));
// error
socket.on('error', (err) => console.error('**ERROR**\n>> : ' + err));
...
to thyme
// to thyme
var net = require('net');
var asClient = net.connect({ port: process.env.ST_PORT });
net을 다시 이용해서 RADAR에서 받은 데이더를 Thyme로 전송하기 위해 연결할 포트를 설정해줍니다.
RADAR(레이더) : CLIENT(클라이언트) —————> RS_PORT : SERVER(서버)
RS_PORT : CLIENT(클라이언트) —————> ST_PORT : SERVER(서버)
[참고] 여기서 RS_PORT는 Radar-to-Server이며, ST_PORT는 Server-to-Thyme 입니다.
encoding
레이더에서 송신하는 값이 16진수로 구성이 되어있어서 hex로 인코딩해주었습니다.
data
클라이언트로 부터 오는 데이터를 처리해주는 함수입니다. 여기서 데이터와 서버가 다시 클라이언트 역할을 수행하므로 그 역할을 해줄 asClient
를 파라미터로 data와 함께 tasHandler
에게 전달합니다.
end
클라이언트로 부터 오는 데이터가 끝났을때 처리해주는 함수입니다. 로그를 출력해줍니다.
close
클라이언트와 접속이 끊어지는 경우 처리해주는 함수입니다. close 함수는 hasErr
, 즉 에러 발생 유무를 반환해주기 때문에 콜백함수로 에러와 함께 종료됐는지 확인할 수 있습니다. 상황에 맞는 로그를 출력해줍니다.
error
클라이언트와 접속에서 오류가 발생했을 때 처리해주는 함수입니다. 로그를 출력해줍니다.
const tasHandler = (data, client) => {
// parseRadarData(data);
if (data === null) {
// socket keep alive only for data is null !
client.setKeepAlive(true, 5000);
}
// send to thyme
client.on('connect', () => {
// data -> trash
if (data.toString().substring(0, 4) !== 'ffff') {
// not working with parsed data ...
// var send = JSON.stringify(parseRadarData(data)).replace(/"([^"]+)":/g, '$1:');
// client.write(JSON.stringify(cin).replace(/\\"/g, "'") + '<EOF>');
var cin = { ctname: 'radar', con: data };
client.write(JSON.stringify(cin) + '<EOF>');
}
});
client.on('error', (err) => console.error(err));
client.on('close', () => client.destroy());
}
위에서 클라이언트가 데이터를 송신 했을 경우 작동되는 함수입니다. data
가 null
인 경우에는 client가 계속 좀비커넥션을 방지하기 위해서 setKeepAlive
를 사용하였습니다.
앞서 tasReady
에서 설정한 port로 성공적으로 연결이 된다면, client.on('connect', callback)
이 실행됩니다. callback
함수안에서는 레이더로부터 수신한 데이터가 잘못된 값인지를 판별하기 위해서 if문을 걸어두었습니다. 잘못된 값이 아닌 경우, thyme가 mobius에게 전송하는 형식에 맞춰서 write
를 해줍니다. 나머지는 error가 발생하거나 close될 때 callback함수를 설정해주었습니다.
⚠️ 현재 mobius에서 제가 만든 json 구조가 내장되어있는 함수에 올바르지 않은 format인지 모르겠으나 json구조를 JSON.stringify()하여 nCube 포트 3105로 전송을 하게되면 parsing error가 발생합니다. 데이터에서 송신한 16진수의 모음으로 이루어진 String 값을 그대로 3105 port로 전송하면 성공적으로 callback함수가 작동하여, 우선 parsing error가 발생하지 않는 String 값으로 코드를 작성하였습니다. 위 코드를 실행하시면 아래 화면처럼 데이터가 쌓이는 것을 확인할 수 있습니다.
MySQL Workbench에서 확인한 모습
⚠️ 간혹 레이더가 스스로 AP를 바꾸는 경우, 다시 AP를 설정해주어야합니다.😅
안녕하세요 docker에서 실행하는 서버랑 Host의 mysql workbench를 연결하려고 Host:localhost, Port:8080으로 진행하였는데 MySQL workbench에서
Lost connection to MySQL server at 'reading initial communication packet', system error: 10060
에러가 발생하였습니다. docker의 sql이랑 Host의 workbench를 어떻게 연결하면 좋을까요?