PiP (Picture-in-Picture API)는 웹 페이지가 다른 창 상단에있는 작은 창에서 비디오를 재생할 수있게 해주는 새로운 실험용 웹 플랫폼 API이다. 이 기능은 사용자가 다른 일을하면서 비디오를 계속보고 싶어하는 비디오 사이트, 예를 들어 텍스트 자습서 비디오를 보면서 텍스트 편집기 등에서 코딩하는 비디오 사이트에 유용하다. 브라우저 버전이나 종류에 따라 지원하지 않을 경우가 있다. 크롬 최신 버전은 지원을 한다.
function runPip(){ if (!document.pictureInPictureElement) { video.requestPictureInPicture() .catch(error => { // Video failed to enter Picture-in-Picture mode. }); } else { document.exitPictureInPicture() .catch(error => { // Video failed to leave Picture-in-Picture mode. }); } }
jQuery를 이용하는 화려한 슬라이더 효과를 주는 라이브러리들이 많이 있다. 그런것 가져다가 사용하면 편할것 같지만 라이브러리 추가하고 설정을 해줘야 한다. 복잡하고 무겁다. 순수 자바스크립트(바닐라 자바스크립트)와 CSS만으로 간단한 슬라이더 효과를 만들어 보자. 세상.. 심플한것이 제일이다.
<script type="text/javascript"> const showing_class = "showing"; const firstSlide = document.querySelector(".slider_item:first-child"); function slide(){ const currentSlide = document.querySelector(`.${showing_class}`); // showing 클래스가 있는 엘리먼트를 찾는다. if(currentSlide){ // 지금 shwoing 클래스를 가진 엘리먼트 다음 엘리먼트에 클래스를 추가 한다. currentSlide.classList.remove(showing_class); const nextSlide = currentSlide.nextElementSibling; // 다음 엘리먼트가 있는지 없는지 체크 후 처리 if (nextSlide){ console.log(currentSlide); nextSlide.classList.add(showing_class); } else {//마지막이면(그다음 형제 엘리먼트가 없으니까) 첫 슬라이드에 추가 함. firstSlide.classList.add(showing_class); }
} else { // showing 클래스가 지정된 엘리먼트가 없으면 첫번째에 추가해 준다.(페이지 시작시) firstSlide.classList.add(showing_class); } }
사실 지금까지 해 왔던게 바로 이 게임패드를 연결해 보려고 했던것이었다. 게임패드 용도에 맞게 하나의 게임이 필요해서 P5.js로 만드는 게임을 지금 까지 해 봤던 것이다. 최신 웹 브라우저에서는 게임패드를 인식하고 사용할 수 있도록 기본으로 되어 있는데, 물론 브라우저마다 안되거나 약간 다른 용법을 사용한것 같기도 하다. 아직 지원하지 않기도 하는 모양이다. 여기서는 윈도우10에서 크롬브라우저를 기준으로 예제를 만들었다. 다른 환경에서 테스트는 해 보지 않았다. 제일 먼저 html 문서를 보자.
-------------------index.html-----------------
<!doctype html>
<html lang="ko">
<head>
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta charset="UTF-8">
<meta name="Description" content="">
<title>P5.JS 연습</title>
<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet">
<style type="text/css">
body{
text-align: center;
margin: 0px;
padding: 0px;
}
p{
font-size: .8em;
}
#defaultCanvas0{
}
</style>
<!--공통-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>
<!--프로젝트 스크립트-->
<script src="sketch19-final.js"></script>
<script src="ship3.js"></script>
<script src="asteroid.js"></script>
<script src="laser.js"></script>
<script src="particle2.js"></script>
<script src="explode.js"></script>
<script src="firework.js"></script>
</head>
<body>
<h1>P5.js Example 19-final(Simple Game)</h1>
<audio autoplay controls preload="auto" loop id="myAudio">
<source src="http://soundimage.org/wp-content/uploads/2014/04/Game-Menu.mp3">
Your browser does not support the audio element.
</audio>
<p>게임패드 이동: 왼편 스틱, 슈팅: 오른쪽 R2, 재시작 : F5, BGM : Music by Eric Matyas www.soundimage.org</p>
</body>
</html>
---------------------------------------------
필요한 자바스크립들은 별도의 파일로 만들고 링크해서 사용하도록 하였다. 이문서는 간단하다.
-----------------sketch.js-----------------
var ship;
var asteroids = [];
var lasers = [];
var font, fontsize = 15;
var health = 100;
var shoot;
var bomb;
let particles = [];//var와 let의 차이를 모르겠음? let이 더 엄격하다 정도만.
var fireworks = [];
function preload(){
shoot = loadSound('sound/laser_shoot.mp3');
bomb = loadSound('sound/bom.wav');
}
function setup() {
createCanvas(800, 480);
//createCanvas(windowWidth,windowHeight);
font="Orbitron";
textFont(font);
textSize(fontsize);
//우주선 생성
ship = new Ship();
//소행성 생성
for(let i =0; i < 10; i++){
asteroids.push(new Asteroid());
}
}
function draw() {
background(0);
// Gamepad
pads = navigator.getGamepads();
pad0 = pads[0];
if(pad0){
// 오른쪽 R2 버튼(앞면 큰 버튼)
if (pad0.buttons[7].value > 0.6 && pad0.buttons[7].pressed == true){
lasers.push(new Laser(ship.pos, ship.heading));//너무 연속적으로 추가 되는 문제
shoot.play();
}
// 스틱
if(pad0.axes[0] >= .5 ){
ship.boosting(true);
} else if(pad0.axes[0] <= -.5) {
ship.boosting(true);
} else if (pad0.axes[1] < -.5){
ship.boosting(true);
} else if (pad0.axes[1] > .5){
ship.boosting(true);
}
}
ship.c = color(100, 255, 100, 255);
// Backgroud Particle
let p = new Particle();
particles.push(p);//draw()에 동작해서 계속해서 객체를 만들어 추가한다.
for(let i = particles.length-1; i >= 0; i--){
particles[i].update();
particles[i].show();
if(particles[i].finished()){
particles.splice(i, 1);
}
}
// Explosion
for(var i = 0; i < fireworks.length; i++){
fireworks[i].run();
if(fireworks.length>10){
fireworks.splice(0, 1);
}
}
//소행성
for (var i = 0; i < asteroids.length; i++){
//소행성과 우주선이 충돌하면
if(ship.hits(asteroids[i])){
//console.log("hit");
ship.c = color(255, 0, 0, 255);
health = health - asteroids[i].r * 0.05;
}
asteroids[i].update();
asteroids[i].render();
asteroids[i].edges();
}
// 레이저
for (var i = lasers.length -1; i >= 0; i--){
lasers[i].update();
lasers[i].render();
// 화면을 벗어나면 제거 해줌
if(lasers[i].offscreen()){
lasers.splice(i, 1);
} else {
// 충돌 감지
for(var j = asteroids.length-1; j >= 0; j--){
if(lasers[i].hits(asteroids[j])){
//console.log('hit');
health = health + asteroids[j].r * 0.1;
if(asteroids[j].r > 10) {
var newAsteroids = asteroids[j].breakup();// 충돌된 소행성을 쪼갠다.
asteroids = asteroids.concat(newAsteroids);
}
fireworks.push(new Firework(lasers[i].pos.x, lasers[i].pos.y));
asteroids.splice(j, 1); //j번째 1개를 제거한다.
lasers.splice(i, 1);
bomb.play();
break;
}
}
}
}
// 우주선
ship.render();
ship.turn();
ship.update();
ship.edges();
// Score
drawScore();
}
// Score and Health
function drawScore(){
fill(255);
if(health <= 0){
text("Game Over", 30, 30);
} else {
text(Math.ceil(health), 30, 30);
}
if (asteroids.length <= 0){
text("You Win", 30, 50);
}
}
----------------------------
메인 스케치 파일이다. 키보드 조작기능은 제거를 했다. 게임패드와 키보드 조작을 다 같이 사용하게 할려면 설정 코드가 더 필요한데 귀찮다. 원래 목적대로 게임패드만 사용하게 해 주자. 이 메인 스케치 이외에 우주선, 소행성, 레이저, 폭발효과를 위한 객체 클래스들이 필요하다. 이걸 다 일일히 여기 적기는 힘들고 자바스크립트 이니 소스가 다 보인다. 찾아서 참고 하면 될듯 하다. ^^;
기본 게임 만드는 유튜브로 만든 것에 필요한 기능 몇가지를 추가해 준것이다. 사운드 효과를 주면 더 게임 다워 진다.
게임패드의 왼쪽 조이스틱(맞나 용어가?)를 이용해서 우주선을 움직이게 하는데 이게 키보드 이동키로 단순히 회전하고 전진하고 하는 것과는 좀 다르게 해 줄 필요가 있었다. 상하좌우 아무곳으로나 이동이 가능하게 해주고 해당 방향으로 움직이면 그 방향으로 우주선 헤드가 돌아 가도록 해줘야 했다. 이것을 구현하는게 난감하게 생각되었는데 의외로 간단히 구현 할 수 있었다.
---------------ship.js-------------------
this.turn = function(){
//this.heading += this.rotation;
this.heading = this.vel.heading();
}
--------------------------------------------
vel 벡터의 heading() 을 적용하니 쉽게 구현이 되었다. 좋아~ 스틱의 움직임에 따라 우주선이 자유롭게 조정이 가능했다. 정밀하게 제어하기는 힘들지만 이정도면 충분해 보인다. 마지막 최종 결과는 아래 링크에서 확인해 보자. 물론 호환이 되는 기본형 게임패드가 있어야 게임이 가능하다. 없는 사람에게는 아무것도 해 볼 수 업다. ^^; 데모 영상은 차후 만들어서 추가해 볼 예정이다.
<script type="text/javascript"> var gamepadInfo = document.getElementById("gamepad-info"); var ball = document.getElementById("ball"); // pos var a = 0; var b = 0; var start; var text = "";
// webkitRequestAnimationFrame var rAF = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.requestAnimationFrame;
var rAFStop = window.mozCancelRequestAnimationFrame || window.webkitCancelRequestAnimationFrame || window.cancelRequestAnimationFrame;
// Check connection window.addEventListener("gamepadconnected", function(e) { var gp = navigator.getGamepads()[e.gamepad.index]; gamepadInfo.innerHTML = "Gamepad connected at index "+gp.index+": "+gp.id+", "+gp.buttons.length+" buttons, "+gp.axes.length+" axes";
배경에 파티클을 이용해서 저 멀리 별들도 그려 주자. 우주공간이 이잖아. 사운드 이펙트는 레이저빔 소리와 행성 쪼개지는 소리(이건 별로 마음에 안듬)를 넣어 주었다. 핼쓰(스코어) 수치도 넣어 주었다. 이제 더이상 할게 없다. ^^; 최종 결과는 아래 링크에서 확인 하자.
다수의 asteroid를 만들어 줘야 한다. 모양도 제각각이다. Asteroid 클스를 이용하여 원하는 갯수만큼 만들어 주면 된다. 여러가지 모양은 vertex를 이용해서 꼭지점의 위치에 무작위 변화를 주어 다른 모양으로 그려 준다. 기본적인 동작은 동일하다. 화면을 벗어 나면 반대편에서 다시 나오게 되어 있다.
P5.js를 이용하여 게임을 만드는 유튜브 동영상을 따라서 간단히(?) 게임을 하나 만들어 보자. 코드를 작성하는게 중요한게 아니고 코드의 의미를 이해하는 것이 더 중요하다. 제일 먼저 우주선 클래스를 만들고 플레이어가 될 우주선을 하나 만들어 키보드에 따라 움직이도록 하는 작업을 하자. 자세한 내용은 아래 링크이 동영상을 참조 하자. 게임의 목표는 떠 돌아 다니는 소행성을 모두 제거하면 된다.
파트1에 이어서 이번에는 좀 더 기능을 추가해 보기로 하자. 앞서 크롬 브라우저에서 음성을 인식하고 텍스트를 화면에 출력해 주는 것 까지 구현이 되었다. 여기다 한글 텍스트를 영문으로 번역하고 그 결과를 음성으로 읽어 주는 기능을 추가하자. 번역 API를 찾아 보니 몇가지 대안이 있는데 강력한 후보이 구글번역 API가 유료로 전환된듯 결제설정을 하라고 나온다. 이런…
구글 Translate API
Microsoft Azure Translate API
Yandex
구글은 유료(정확하지 않음)이고 마이크로소프트는 12개월 무료인데 그후엔 유료라고 한다. 결국 선택한것은 Yadex라는 API 서비스이다. 그런데 문제는 번역 품질이 시원찮다. 일단 흐름을 파악하기 위해서 이것을 이용해 보기로 하자.
var message = document.querySelector("#message"); var button = document.querySelector("#speech"); var korea = document.querySelector("#korea"); var english = document.querySelector("#english"); var isRecognizing = false;
if ('SpeechRecognition' in window) { // Speech recognition support. Talk to your apps! console.log("음성인식을 지원하는 브라우저입니다.") }
try { var recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition)(); } catch(e){ console.error(e); }
function stop(){ recognition.stop(); message.innerHTML = "버튼을 누르고 아무말이나 하세요."; button.disabled = false; button.innerHTML = "Start STT"; isRecognizing = false; }
// Text to speech function text_to_speech(txt){ // Web Speech API - speech synthesis if ('speechSynthesis' in window) { // Synthesis support. Make your web apps talk! console.log("음성합성을 지원하는 브라우저입니다."); } var msg = new SpeechSynthesisUtterance(); var voices = window.speechSynthesis.getVoices(); //msg.voice = voices[10]; // 두번째 부터 완전 외국인 발음이 됨. 사용하지 말것. msg.voiceURI = 'native'; msg.volume = 1; // 0 to 1 msg.rate = 1.3; // 0.1 to 10 //msg.pitch = 2; //0 to 2 msg.text = txt; msg.lang = 'ko-KR';
전체 코드인데 제대로 된건지는 아직 모르겠다. 일단 작동은 하니깐. 여러가지 메소드들이 있는데 정확한 사용법은 앞으로 예제를 더 만들어 보면서 바로 잡도로 하자. 예제는 단순히 앞 음성인식이 끝이 나면 자도으로 다시 음성인식을 시작하도록 하였다. 다른 방법도 있을것 같은데 … 자세한 내용은 아래 사이트를 참조 하자.
앞서 만들고 있는 Node.js로 만든 홈페이지를 무료로 Heroku(히로쿠) 에 올려서 누구나 접속 하도로고 해보자. 배포라는 말을 쓰기도 하는것 같은데 홈페이지를 배포한다고? ^^; 아직 완성이 안된것이지만(언제 끝이 날지도 모르고 해서) 배포를 어떻게 하는지 그 절차가 궁금하다. 이 작업은 윈도우에서 해도 되고 리눅스나 라즈베리파이에서도 가능하다. 일단 기존에 작업을 라즈베리파이에 올려서 하던 중이니 라즈베리파이에서 해보기로 하자.
Heroku는 헤로쿠는 웹 애플리케이션 배치 모델로 사용되는 여러 프로그래밍 언어를 지원하는 클라우드 PaaS이다. PaaS? 이건또 뭐냐? 아뭏든 이것을 이용하면 Node.js로 만든 홈페이지를 공개할 수 있다는 것 같다. 일단 무료인데 조건이 좀 까다롭다. 접속자가 없으면 잠자기 모드로 들어간다고 한다. 자세한 것은 아래 사이트에서 확인 하자. https://www.heroku.com
라즈베리파이에서 진행하는 간단한 절차 sudo apt update sudo apt install snapd sudo reboot
이제 snap을 설치했으니 heroku cli를 설치하면 된다. cli는 명령 줄 인터페이스라는 뜻이다. 한마디로 터미널로 조작하는 거인듯 … sudo snap install heroku –classic heroku login
터미널 상태에서 로그인을 지원하지 않는다. 주소를 보여주는데 그 주소를 복사해서 아무 컴 브라우저를 열어서 접속하여 로그인을 진행하면 된다. 그리고 브라우즈는 닫아도 된다. 그러면 터미널에서 로그인 된 상태로 진행이 되어 있다. 로그인이 되었으면 간단히 heroku로 부터 기본 프로젝트를 하나 clone해서 동작을 시켜 보기로 하자. git clone https://github.com/heroku/node-js-getting-started.git cd node-js-getting-started/
패키지를 열어 보면 필요한 의존성 패키지 정보가 들어 있다. 이것을 라즈베리파이에서 실행해 볼려면 이 패키지들을 이 프로젝트에 설치해서 줘야 한다. npm install
해주고 이 프로젝트를 실행시켜 보자. node index.js
포트 5000번으로 서버가 실행되었다고 터미널에 출력된다. 이제 웹브라우저로 접소개 보자.
잘 들어 간다. 앞에서 다운로드 받은 프로젝트가 이런 모양이라는 것이다. 이 기본틀을 가지고 사용자가 원하는 모양으로 수정해서 자신의 홈페이지를 만들거나 아니면 독자적으로 원하는 형태의 홈페이지를 만들면 된다는 것이다. 어쨌든 이렇게 저렇게 홈페이지를 만들었다면 이제 이것을 다시 heroku에 올려서 배포를 시켜야 한다. 이 샘플을 사용할것은 아니고 앞서 만들고 있는 홈페이지를 업로드 시켜 보기로 하자. heroku create ghostsocket01
Heroku에 저장소를 만들어야 한다. 그냥 create하면 랜덤 이름으로 만들어주는것 같다. 프로젝트 이름으로 만들어 주면 될듯 하다. 중복되는 이름이 있으면 생성되지 않는다.
공식 가이드에는 언급이 없지만 로컬 저장소에서 파일 수정이 있거나 하면(있어야 가능한듯) commit를 해주는 과정이 필요한듯 하다. 일부러 쓸데 없는 파일 만들고 하라고 하는 사람도 있다. git add . git commit –m “message…블라블라”
하고 나서 push를 해줘야 한다. git push heroku master
라고 하면 된다고 가이드에는 되어 있는데 이것은 다운로드 받은 것을 그대로 수정해서 하는 경우를 염두에 두고 한 듯 하다. 내가 작업 중이든 프로젝트를 올리려고 하니 에러 나고 난리도 아니다. git 자체에 config 설정이 빠진 부분이 있어서 수정했다. 이메일과 이름을 설정하라는 에러이다. 설정하고 다시 시도 하니 또 에러다. npm start 가 설정이 안되어 있다는 것 같다. 음~ 이건 또 뭔가? { "name": "web2018", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "start": "node app.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "body-parser": "^1.18.3", "ejs": "^2.6.1", "express": "^4.16.4" }
}
빨간색 부분이 누락되어 있어서 추가해 주었다. 최초 실행되는 스크립트 파일명을 적어 주는 듯 하다. 로컬에서 할땐 언급 없더니? 아뭏든 이렇게 수정하고 다시 시도! 또 에러가 업로드는 되었는데 해상 사이트가 열리지 않고 에러가 난다. 일단 오픈하는 과정은 아래와 같다. heroku ps:scale web=1
이건 의미를 모르겠다. 일단 하자. heroku open
하면 윈도우라면 자동으로 웹브라저가 열리면서 오픈이 되는 모양인데 라즈베리파이라서 웹브라우저를 열지 못하는 건지 열리지 않고 메세지를 출력한다.
직접 저 주소로 웹브라우저 접속해 보라는 것이다. https://ghostsocket01.herokuapp.com 이게 내 사이트 주소가 된다. 이름을 막 지을게 아니네…!
그런데 또 에러다… 오마이캇! 문제는 포트관련 작성 방법이다. app.js파일을 수정하자. var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended : true}));
app.set('view engine', 'ejs');//ejs 템플릿 엔진 연동 // route setting - 라우팅(routing)
app.get('/', function (req, res) { //res.send('Hello World!'); var data = req.body.name; res.render('index', {name: data});//views디렉토리안에 있는 index.ejs 파일
}); app.listen(process.env.PORT || 5000, function(){ console.log('App Listening on port 5000');
});
포트번호는 문제가 아닌데 단순히 포트번호만 적지 말고 process.env.PORT를 같이 기술해 줘야 하는가 보다. 이렇게 수정하고 다시 오픈을 해보니 정상적으로 동작한다. 초기에 샘플로 받은 프로젝트에 index.js파일을 열어 보면 이런식으로 되어 있는 것을 확인 할 수 있다. 대충 보고 했더니 ….
이렇게 하면 내 로컬에 있던 node.js로 만든 사이트를 인터넷에 공개 할 수 있다. https://ghostsocket01.herokuapp.com
궁금하면 … ^^ 아직 작업중인것이라서 … 대충 이런 흐름으로 heroku 를 이용하여 앱을 배포할 수 있다는 것이다. 중간에 에러가 나서 개고생했는데 에러 메세지나 구글 검색으로 해결을 해가면서 작업을 진행하면 될듯 하다. 처음 다운로드 받은 샘플을 잘 검토 하고 적용하면 될듯 하다.
heroku가 무료라서 좋지만 그렇게 마음 놓고 쓰기는 힘들어 보인다. 그냥 개인 사이트로 활용하기는 문제는 없어 보인다. 속도도 느리다는 평가이고 시간 제한도 있고 … 다른 솔루션이 있는지 더 찾아 보기로 하자.
최대한 간단하게라도 일일히 홈페이지를 만들려니 귀찮다. 이럴때는 템플릿을 이용하면 된다. 무료로 다운로드 가능한 템플릿을 검색해 보면 엄청 많다. 이 보다 더 잘 만들수가 없다. 원하는 템플릿을 찾았다면 다운로드 받자. 보통 index.html 파일과 CSS/JS/Image등으로 디렉토리 별로 잘 정리 되어 있다. 이걸 작동중이 Node.js서버에 그대로 올려 주면 된다.
문제는 index.html 파일이다. 확장자를 그대로 올려는 안된다. 지금 Node.js 에서 ejs 템플릿 엔진을 사용하고 있으니 확장자를 ejs로 변경해 줘야 한다. 그리고 index파일만은 views 디렉토리에 업로드 해줘야 한다. 나머지 css/fonts/images/js 디렉토리는 public 디렉토리 안에 그대로 업로드 해주면 된다. 이렇게 해서 아무런 문제가 없으면 정말 다행이다. 그런데 뭔가 문제가 발생되면 수정하기가 골치 아프다. 다른 사람이 만들어 놓은것이라서 찾기가 간단하지 않다. 행운을 빌어야지…
수많은 템플릿 중에서 하나를 다운로드 받아서 Node.js서버에 올렸다. 아무런 문제가 없다. 잘 동작한다. 이제 내용만 변경해 주거나 약간 손을 보면 된다. One page 홈페이지이다. 당장은 콘텐츠랄게 없기 때문에 페이지 하나면 다 해결된다. index 페이지에 부하가 많이 걸릴수 있지만 이정도는 문제 없을것으로 생각된다.
중간 결과물 - 대충 이런 느낌이다. 쉽게는 텍스트나 이미지만 교체를 해주고 링크만 손을 보면 된다. 여기다 원하는 기능을 첨가 해 주면 될듯 하다. 메인 메뉴를 클릭하면 스크롤 되어 해당 영역으로 이동되는 방식이다.
설치후 package.json 내용을 보면 의존성에 추가 되어 있는 것을 확인 할 수 있다. Express는 앱개발 프레임워크이고 ejs는 템플릿 엔진이다. 이것말고 pug(jade)라는 것도 있던데 … 이건 뭐 다시 새로운 문법을 배워야 한다. 된장. 지금도 머리 아파 죽겠는데 새로운 체계를 배우라고? 그래서 기존의 html 문법을 그대로 사용할수 있는 ejs를 사용하기로 했다. 그렇게 복잡한 사이트를 만들것도 아니고 일단 ejs로 하자. 어느게 좋은지 그런건 아직 모르겠다.
app.js라는 파일은 생성하고 코드를 아래와 같이 작성하자.
var express = require('express');
var app = express();
app.get('/', function (req, res) { res.send('Hello World!');
});
app.listen(3000, function(){ console.log('App Listening on port 3000');
});
저장 하고 실행해 보자.
node app.js
이제 웹브라우저에서 raspberrypi_ip:3000 으로 접속하면 Hello World라고 출력되는 것을 확인 할 수 있다. 이제 ejs 템플릿을 이용해서 만들어 보자. ejs는 앞서 언급했듯이 기존 HTML를 그대로 사용할 수 있다. 그래 이게 좋은거지. 여기에다 <% %>를 사용하여 서버의 데이터나 코드를 실행할 수 있게 된다. ejs를 사용하기 위해서 app.js에 설정을 해줘야 한다.
var express = require('express');
var app = express();
// app.set('views', './views');
app.set('view engine', 'ejs');//ejs 템플릿 엔진 연동
// route setting - 라우팅(routing)
app.get('/', function (req, res) { //res.send('Hello World!'); res.render('index');//views디렉토리안에 있는 index.ejs 파일
});
app.listen(3000, function(){ console.log('App Listening on port 3000');
});
코드에서 알수 있듯이 views라는 디렉토리를 만들어 주고 그 안에 html 문서를 넣어 주면 된다. send 대신에 render라는 메소드를 사용하는 것도 유의하자. HTML문서의 확장자가 .html이 아니라 .ejs라고 해서 저장해야 한다. 샘플로 html문서는 아래와 같이 해주자.
<!DOCTYPE html>
<html>
<head> <meta charset="utf-8"> <title>Ghost</title>
</head>
<body> <h1>Ghost</h1> <p>샘플 사이트입니다. 앞으로 계속 추가해 나가도록 하겠습니다.</p>
</body>
</html>
이렇게 저장해주고 다시 app.js를 실행하고 브라우저에서 접속해 보면 html 내용이 출력되는 것을 확인 할 수 있다. 이것이 기본적인 사용법이다.
app.js 재실행시 이미 포트를 사용중이라고 에러가 나면 다음과 같이 해주자.
ps –ef | grep app.js
pid번호를 확인하고 죽이면 된다.
kill –9 <pid_num>
프로젝트 전체의 파일 구조를 보면 아래와 같이 되어 있다.
<% %>의 사용법을 알아 보자. app.js로 부터 데이터를 전송 받아서 브라우저에 출력하는 것으로 만들어 보자. 지금까지는 get을 사용했지만 이번에는 post를 사용해야 한다. html은 다음과 같이 수정했다.
<!DOCTYPE html>
<html>
<head> <meta charset="utf-8"> <title>Ghost</title> <link rel="stylesheet" type="text/css" href="stylesheet">
</head>
<body> <h1>Ghost</h1> <p>샘플 사이트입니다. 앞으로 계속 추가해 나가도록 하겠습니다.</p> <h3><%= name %>님 반갑습니다.</h3>
form의 내용을 post 로 넘긴다. app.js를 수정하자. 여기서 다시 필요한것이 있다.
npm install body-parser –save
설치를 했으면 app.js를 수정하기로 하자.
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended : true}));
app.set('view engine', 'ejs');//ejs 템플릿 엔진 연동
// route setting - 라우팅(routing)
app.get('/', function (req, res) { //res.send('Hello World!'); var data = req.body; res.render('index', {name: data});//views디렉토리안에 있는 index.ejs 파일
});
app.post('/', function (req, res) { var data = req.body.name; res.render('index', {name: data});
});
app.listen(3000, function(){ console.log('App Listening on port 3000');
});
이름을 입력하고 submit 하면 입력된 이름을 출력해 준다. 지금까지 기본적인 흐름을 파악하기 위해 기초적인 사항들을 다루어 보았다. 이제 본격적으로 그럴싸한 홈페이지를 만들어 보기로 하자.
이번에는 Socket.io를 이용해서 안드로이드와 소켓통신을 해보기로 하자. 먼저 Node.js로 서버를 가동하자. 여기서 express라는 것을 이용할텐데 이 express는 Node.js에서 동작하는 웹 개발 프레임워크이다. 한마디로 편하게 웹서버를 가동하고 개발할 수있도록 해주는 것이니 이용하기로 하자. 편한길로 가야지. express(이것도 뭔가 복잡한데 다음에 알아 보자.)를 사용하기 위해서 먼저 설치를 해줘야 한다. 그리고 socket.io도 설치하자.
npm install express
npm install socket.io
이제 서버코드를 작성하자.
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000, function(){ console.log('listening on *:3000');
});
io.sockets.on('connection', function (socket){ //원격에서 접속이 되면 기본 응답 socket.emit('message_from_server', 'hello, world');
//메세지가 들어 오면 응답 socket.on('message_from_client', function (msg){ console.log('message:', msg); /*받은 메세지를 되돌려 주자. 아니면 받은 데이터를 이용 라즈베리파에서 뭐든 할 수 있다. */ socket.emit('message_from_server', '"' +msg+ '" 라고하셨군요.'); });
});
간단히 소켓으로 받은 데이터를 되돌려 전송하는 코드이다. 실행해 두자.
node server.js
이제 원격 자바스크리트로 클라이언트를 만들자.
텍스트를 입력하고 전송하면 서버에서 그 값을 되돌려 받아서 화면에 출력하게 된다. 라이브러리를 추가해 줘야 하는데 아래 사이트에서 복사해 넣자.
<script type="text/javascript"> var socket = io.connect("192.168.0.4:3000"); var res = document.querySelector("#response"); var msg = document.querySelector("#inputMsg");