문제

- sql실습
stockInfo 테이블 생성 후
stockName(varchar 100), stockUrl (varchar 500) 컬럼 생성, 선정한 주식 5종목 정보 저장(naver 증권에서 url 추출)

-오픈소스 프로그래밍
80포트 사용
/ 접속시 페이지 로드
/main 접속시 페이지 로드
/getStockInfo API : DB에 저장된 주식 목록 조회
/getStockPrice API : DB에 저장된 해당 주식의 url로 네이버 request를 전송하여 가격을 조회

-웹ui
selectbox에 DB에 저장된 5개 종목을 선택할 수 있게 하여 가격보기 버튼을 클릭 시
현재시점부터 최대 30초까지의 주식 정보를 1초에 한번씩 실시간으로 그래프로 출력

- 제출파일
1. heidisql에서 테이블 오른쪽버튼 클릭 -> 데이터베이스를 sql로 내보내기 후 데이터베이스 생성x, 테이블 생성x -> db.sql로 파일 저장
2. app.js 서버파일
3. main.html html파일
제목 : 이름_기말고사
세 파일을 압축 후 파일 첨부해서 870222@hanmail.net 으로 제출

 

방법 1.

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("\n\nServer is running...\n\n")

var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

app.get('/', function (req, res) {
  res.sendfile("stockList.html");
});
app.get('/main', function (req, res) {
  res.sendfile("stockList.html");
});

app.get('/realTimePrice', function (req, res) {
  res.sendfile("realTimePrice.html");
});

// 메인 페이지 접속시 stockInfo 테이블 정보를 가져오는 라우터
app.get('/getStockInfo', function (req, res) {
  var query = `SELECT * FROM stockInfo`;
  connection.query(query, function (err, rows, fields) {
      if (err) throw err;
      // console.log(rows);
      res.send(rows);
    }
  );
});

// 실시간 주식 정보를 가져오는 라우터
app.get('/getStockPrice', function (req, res) {
  var name = req.query.company;
  var query = `SELECT stockUrl FROM stockInfo WHERE stockName = '${name}'`;
  connection.query(query, function (err, rows, fields){
    if (err) throw err;
    // var response = JSON.stringify(rows); // 이렇게 하면 Object를 [{"stockUrl":"https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660"}] 로 변환해준다.
    var targetUrl = rows[0].stockUrl;
    const options = {
      url:`${targetUrl}`,
      method: 'GET'
    }

    request.get(options, function(err,httpResponse,body){
      response = JSON.parse(httpResponse.body);
      var price = response.result.areas[0].datas[0].nv;
      res.send(''+price);
    });
  });
});


// 서버 기동시 매 초마다 DB에 주식 정보를 기록
const hynix = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660',
  method: 'GET'
}
const coway = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:021240|SERVICE_RECENT_ITEM:021240',
  method: 'GET'
}
const lgelectronics = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:066570|SERVICE_RECENT_ITEM:066570',
  method: 'GET'
}
const cj = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:001040|SERVICE_RECENT_ITEM:001040',
  method: 'GET'
}
const chongkundang = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:185750|SERVICE_RECENT_ITEM:185750',
  method: 'GET'
}
setInterval(function () {
  request.get(hynix, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO hynix (price) VALUES('${price}');`)
  });
  request.get(coway, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO coway (price) VALUES('${price}');`)
  });
  request.get(lgelectronics, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO lgelectronics (price) VALUES('${price}');`)
  });
  request.get(cj, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO cj (price) VALUES('${price}');`)
  });
  request.get(chongkundang, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO chongkundang (price) VALUES('${price}');`)
  });
},1000);

 

stockList.html (http://localhost/)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>주식 리스트</title>
  </head>
  <body>
    <h>주식 리스트 페이지입니다</h>
    <input type="button" value="실시간 주식 정보 조회하러 가기" id="mainBtn" onclick = "goToRealTimePrice()">
    <br><br>
    <span id="stockList"></span>

  </body>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  $.ajax({
    url : 'getStockInfo',
    data : {
    },
    success : function(res){
      $("#stockList").append(`저장된 주식 리스트는 다음과 같습니다.<br>`);
      for (var i=0; i<res.length; i++) {
        var name = res[i].stockName;
        $("#stockList").append(`${name}<br>`);
      }
    }
  });

  function goToRealTimePrice() {
    location.href = "/realTimePrice"
  }
</script>
</html>

 

realTimePrice.html (http://localhost/realTimePrice)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>실시간 주식 정보</title>
  </head>
  <body>
    <h>실시간 주식 정보 페이지입니다</h>
    <input type="button" value="주식 리스트 보러 가기" id="mainBtn" onclick = "goToStockList()">
    <br>
    <select name="company" id="company">
      <option value="hynix">하이닉스</option>
      <option value="coway">코웨이</option>
      <option value="lgelectronics">LG전자</option>
      <option value="cj">CJ</option>
      <option value="chongkundang">종근당</option>
    </select>
    <input type="button" value="가격보기" onclick="sendRequest()">
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  function goToStockList() {
    location.href = "/"
  }

  var time;
  var stockPrice;
  var graphValue = [];
  var myGraph;
  // var graphValue = new Array(30);

  function sendRequest() {
    // 버튼 누를 때 초기화
    time = 0;
    graphValue = [];
    clearInterval(myGraph);
    var company = $("#company option:selected").val();
    // 버튼 누른 후 반복되는 부분
    myGraph = setInterval(function () {
         $.ajax({
           url : '/getStockPrice',
           type : 'GET',
           data : {
             company : `${company}`
           },
           success : function(res) {
             stockPrice = res;
             // console.log(res);
             graphValue.push([time,Number(stockPrice)])
             if (graphValue.length > 30) {
               graphValue.shift();
             }
             time++;
             drawCurveTypes(graphValue);   // 구글 차트를 그려주는 함수를 호출한다.
           }
         });
     },1000);
  };

  google.charts.load('current', {packages: ['corechart', 'line']});
  google.charts.setOnLoadCallback(drawCurveTypes);

  function drawCurveTypes() {
    var data = new google.visualization.DataTable();
    data.addColumn('number', '시간(초)');
    data.addColumn('number', '가격');
    // data.addColumn('number', `${company}`);

    data.addRows(graphValue);

    var options = {
      hAxis: {
        title: '시간(초)'
      },
      vAxis: {
        title: '가격(원)'
      },
      series: {
        1: {curveType: 'function'}
      }
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }

  </script>
</html>

방법 1은 realTImePrice.html이 서버에 요청을 보내면 /getStockPrice 라우터가 매 초 요청이 들어올 때마다 DB에서 URL을 새로 가져왔다. 그래서 방법 2에서 버튼을 누르면 setInterval이 시작되기 전에 /getStockInfo 라우터에 한 번 가서 URL을 가져오고 그것을 변수에 담아 /getStockPrice에 요청을 보내도록 수정했다. (방법 2가 방법 1보다 서버 부하를 줄이기 위해 개선되었음)

하지만 방법 1에서 배울 부분DB가 주는 response는 언제나

[
    { Key1 : Value1,
      Key2 : Value2,
      Key3 : Value3
    }
]

형태의 객체라는 것이다.

자바에서 DB가 보내주는 response를 ResultSet으로 받아서 객체의 i번째의 Key로 Value를 가져와 String으로 변환했던 것을 생각하자.

 

자바스크립트에서도 마찬가지로 객체의 i번째의 Key에 접근해서 Value를 가져와야한다.

첫 번째 방법은,

var response = JSON.stringify(rows);    이렇게 하면 Object를

[{"stockUrl":"https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660"}]

로 변환해준다. Object에서 이제 우리가 볼 수 있는 자료의 모습으로 바꿔주었고, 그 다음 response[0].stockUrl을 하면 된다.

 

두 번째 방법은 자바스크립트는 관대한 언어라 바로 이렇게만 해도 꺼내올 수 있다.

var targetUrl = rows[0].stockUrl;

 

 

방법 2.

app.js와 realTimePrice.html 2개만 바뀌었다.

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("\n\nServer is running...\n\n")

var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

app.get('/', function (req, res) {
  res.sendfile("stockList.html");
});
app.get('/main', function (req, res) {
  res.sendfile("stockList.html");
});

app.get('/realTimePrice', function (req, res) {
  res.sendfile("realTimePrice.html");
});

// 메인 페이지 접속시 stockInfo 테이블 정보를 가져오는 라우터, 실시간 주식 정보 페이지에서 '가격보기' 버튼 클릭시 해당 기업 주식 URL 정보 가져오는 라우터
app.get('/getStockInfo', function (req, res) {
  var query = `SELECT * FROM stockInfo`;
  connection.query(query, function (err, rows, fields) {
      if (err) throw err;
      // console.log(rows);
      res.send(rows);
    }
  );
});

// 실시간 주식 정보 페이지에서 '가격보기' 버튼 클릭시 주식 정보 읽어오는 라우터
app.get('/getStockPrice', function (req, res) {
  var stockUrl = req.query.stockUrl;
  const options = {
    url:`${stockUrl}`,
    method: 'GET'
  }
  request.get(options, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    res.send(''+price);
  });
});

// 서버 기동시 매 초마다 DB에 주식 정보를 기록
const hynix = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660',
  method: 'GET'
}
const coway = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:021240|SERVICE_RECENT_ITEM:021240',
  method: 'GET'
}
const lgelectronics = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:066570|SERVICE_RECENT_ITEM:066570',
  method: 'GET'
}
const cj = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:001040|SERVICE_RECENT_ITEM:001040',
  method: 'GET'
}
const chongkundang = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:185750|SERVICE_RECENT_ITEM:185750',
  method: 'GET'
}
setInterval(function () {
  request.get(hynix, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO hynix (price) VALUES('${price}');`)
  });
  request.get(coway, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO coway (price) VALUES('${price}');`)
  });
  request.get(lgelectronics, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO lgelectronics (price) VALUES('${price}');`)
  });
  request.get(cj, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO cj (price) VALUES('${price}');`)
  });
  request.get(chongkundang, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO chongkundang (price) VALUES('${price}');`)
  });
},1000);

 

realTimePrice.html (http://localhost/realTimePrice)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>실시간 주식 정보</title>
  </head>
  <body>
    <h>실시간 주식 정보 페이지입니다</h>
    <input type="button" value="주식 리스트 보러 가기" id="mainBtn" onclick = "goToStockList()">
    <br>
    <select name="company" id="company">
      <option value="hynix">하이닉스</option>
      <option value="coway">코웨이</option>
      <option value="lgelectronics">LG전자</option>
      <option value="cj">CJ</option>
      <option value="chongkundang">종근당</option>
    </select>
    <input type="button" value="가격보기" onclick="sendRequest()">
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  function goToStockList() {
    location.href = "/"
  }

  var time;
  var stockPrice;
  var graphValue = [];
  var myGraph;
  // var graphValue = new Array(30);

  function sendRequest() {
    // 버튼 누를 때 초기화
    time = 0;
    graphValue = [];
    clearInterval(myGraph);
    var company = $("#company option:selected").val();
    var stockUrl;
    $.ajax({
      url : 'getStockInfo',
      data : {
      },
      success : function(res){
        for (var i=0; i<res.length; i++) {
          if (company == res[i].stockName) {
            stockUrl = res[i].stockUrl;
            return;
          }
        }
      }
    });

    // 버튼 누른 후 반복되는 부분
    myGraph = setInterval(function () {
         $.ajax({
           url : '/getStockPrice',
           type : 'GET',
           data : {
             stockUrl : `${stockUrl}`
           },
           success : function(res) {
             stockPrice = res;
             // console.log(res);
             graphValue.push([time,Number(stockPrice)])
             if (graphValue.length > 30) {
               graphValue.shift();
             }
             time++;
             drawCurveTypes(graphValue);   // 구글 차트를 그려주는 함수를 호출한다.
           }
         });
     },1000);
  };

  google.charts.load('current', {packages: ['corechart', 'line']});
  google.charts.setOnLoadCallback(drawCurveTypes);

  function drawCurveTypes() {
    var data = new google.visualization.DataTable();
    data.addColumn('number', '시간(초)');
    data.addColumn('number', '가격');
    // data.addColumn('number', `${company}`);

    data.addRows(graphValue);

    var options = {
      hAxis: {
        title: '시간(초)'
      },
      vAxis: {
        title: '가격(원)'
      },
      series: {
        1: {curveType: 'function'}
      }
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }

  </script>
</html>

방법 1은 realTImePrice.html이 서버에 요청을 보내면 /getStockPrice 라우터가 매 초 요청이 들어올 때마다 DB에서 URL을 새로 가져왔다. 그래서 방법 2에서 버튼을 누르면 setInterval이 시작되기 전에 /getStockInfo 라우터에 한 번 가서 URL을 가져오고 그것을 변수에 담아 /getStockPrice에 요청을 보내도록 수정했다. 수정을 위해 app.js realTimePrice.html이 바뀌었다.

 

 

 

DB

더보기

stockInfo

CREATE TABLE javascript.stockInfo (
	stockName varchar(100) NULL,
	stockUrl varchar(500) NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

hynix

CREATE TABLE javascript.hynix (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

coway

CREATE TABLE javascript.coway (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

lgelectronics

CREATE TABLE javascript.lgelectronics (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

cj

CREATE TABLE javascript.cj (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

chongkundang

CREATE TABLE javascript.chongkundang (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

 

네이버 주식 real time 기본 폼

더보기

기말고사 제출본.7z
0.04MB

+ Recent posts