DB의 변경 데이터 실시간 모니터링 하는 웹 화면 구현
조회수 16593회
안녕하세요.
오랜만에 막힘을 해결하기 위해 해시코드를 찾아왔습니다.
항상 답변 고맙습니다.
node.js 환경에서 개발 중입니다.
mysql를 사용 중이고, 예를 들면 tb_test 테이블에서 msg, value 컬럼을 생성하였습니다.
<tb_test>
no(pk) msg value
1 'test' 1
2 'hello 32
위처럼 데이터가 삽입되어 있을 때,
pk 1의 value가 1 에서 382 로 업데이트 된다던가
pk 3의 새로운 튜플이 생성된다던가
경우를 실시간으로 감지하여 웹 사용자에게 모니터링 할 수 있도록 구현하려고 합니다.
현재 socket.io 를 사용하여,
<index.html>
var socket = io();
$('#add_status').click(function() {
socket.emit('status added', $('#comment').val());
});
socket.on('refresh feed', function(msg) {
$('#show_comments').append(msg + '<br /><br />');
});
<app.js>
io.on('connection', function(socket) {
console.log('A user is connected');
socket.on('status added', function(status) {
add_status(status, function (res) {
if (res) {
io.emit('refresh feed', status);
} else {
io.emit('error');
}
});
});
});
var add_status = function (status, callback) {
pool.getConnection( function (err, conn) {
if (err) {
callback (false);
return;
}
const insertQuery = ' INSERT INTO tb_test (msg, createdAt) VALUES '
+ ' ( '
+ mysql.escape(status)
+ ' , now() '
+ ' ) ';
console.log(insertQuery);
conn.query(insertQuery, function (err, rows) {
conn.release();
if (!err) {
callback (true);
}
});
conn.on('error', function (err) {
callback (false);
return;
});
});
}
같은 방법으로 웹에서 메시지를 입력 후 버튼을 누르면,
입력한 메시지를 db에 저장함과 동시에 웹에서 <div id="show_comments"></div>
에 삽입하여 보여주도록 하는 것 까지는 구현할 수 있었습니다.
DB 데이터의 변경(insert, update, delete)시 그것을 감지하여 웹에 보여주려면 어떻게 해야 하는지 조언 부탁 드리겠습니다.
4 답변
-
html5 의 웹소켓을 이용해서 접속된 클라이언트들에 데이터를 push(broadcast)할 수 있습니다.
mysql 의 trigger를 사용해서 데이터 변경시 콜백처리를 할 수 있습니다.
http url을 호출 가능하도록 mysql udf를 만들고 trigger에서 해당 udf를 호출하여 서버쪽에 변경된 데이터등을 전송할 수 있습니다. 서버에서는 받은 데이터를 웹소켓에 연결되어 있는 클라이언트들에게 push 할 수 있습니다.
예전에는 실시간 웹의 구현을 comet 기술로 long polling등을 사용했으나 html5 가 표준인 지금에서는 웹소켓으로 편하게 구현할 수 있습니다.
- 이제 봤네요 답변 감사합니다! 결국 디비쪽 트리거를 이용하는 방법 밖에 없는 것 같군요. mysql 이 될수도 있고 mssql 이 될 수도 있는 상황인데요. / 10초, 30초, 60초 등 한 번씩 갱신하여 실시간으로 보여주는 형태도 충분한 성능을 낼 수 있을 것 같은데, socket.io 와 setInterval ? 을 같이 사용하면 구현할 수 있을까요? 상남자 2017.4.15 22:45
- 폴링을 하는 형태는 좋은 방법이 아닙니다. 변경이 없는 상황인데도 계속 부하를 줄 수밖에 없는 구조이고 다수의 클라이언트가 연결되어 있는 상황이면 더더욱 악영향이 될 수 밖에 없는 구조입니다. 웹소켓이 다루기 어려운 기술이 아니니 학습을 진행해보시면 좋을 듯 합니다. 정영훈 2017.4.17 12:15
-
전제조건이 DB데이터의 변경이라면 이벤트가 발생되는 주체는 DB서버가 되어야 겠죠. 이런 생각을 저도 해본적이 없어서리 자료를 찾아보니 트리거가 있더군요 https://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html
한군데 테이블에 변경이력을 모아놓고 그걸 화면에 보여주면 구현은 가능할 것으로 보입니다.
아니면 mysql의 로그를 뒤져 실행된 SQL구문을 분석하여 데이터를 수집하는 방법도 있겠네요.
-
(•́ ✖ •̀)
알 수 없는 사용자
-
-
가장 단순한 방법으로는
데이터가 크지 않다면 Object 식으로 DataSet을 JS 로 들고 있고, 바뀐 부분만 키/데이터 받아서 업데이트...
Last_Update 컬럼 같은걸로 sysdate()를 넣고 마지막으로 DB 쿼리한 시간 이후로 하거나, UPDATE/INSERT 시 FLAG Column을 넣는 방법도 있을 것 같네요.
감사합니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
-
-
node.js의 사례는 모르지만 Ruby on Rails라면 이렇게 할 것 같아 의견드립니다.
어차피 Insert/Update/Delete 명령을 node.js에서 날리는것 아닌가요? 그렇다면 서버에서 처리할 수도 있겠습니다. 해당 테이블의 값 변경을 담당하는 특정 클래스를 하나 만들고 거기에서 변경이 있을때 원하는 처리를 해 주는거지요.
Ruby on Rails의 경우 모델을 통해서 DB의 테이블에 값을 쓰는데요. DB의 값이 변경될 때 마다 호출되는 메소드가 있습니다.(before_create, before_save 등) 여기서 원하는 작업을 해 주면 되서 편해요.
댓글 입력