node에서 express를 이용해서 간단한 웹 서버 테스트를 해보겠습니다.

console 모드에서 작업하는걸 기준으로 테스트 합니다.


기존에 node.js가 설치되어 있어야 합니다.

expressnode에 기본으로 들어있지 않아 설치 해야 합니다.

local용으로 설치가 어떻게 되는지 테스트만 하기 때문에 –g 옵션은 생략 합니다.


nodejs express console

 

설치 명령은 다음과 같습니다.


>npm install express@2.5.x




설치를 하면 node_modules 디렉토리가 생성되고 하위 디렉토리는



이렇게 생성이 됩니다.



그런데 저는 2.x가 아닌 최신 버전으로 테스트 하려고 합니다.

 

동일한 명령어로 npm insall express라고하면 설치는 진행 됩니다.

 

그러나 express 4.0부터는 설치 명령어가 변경 되었습니다.

 

만약에 기존 명령어로 express 4.0이상을 설치하고 프로젝트를 생성하면

설치는 되는데 프로젝트를 생성 할 때 오류가 발생 합니다.




그럼 express 4.0이상을 설치하는 제대로 된 명령어로 설치를 해 볼까요?

버전을 적지 않았으니 최근 버전이 설치가 되겠죠.


>npm install -g express-generator


이렇게 하면 4.0 이상 최신 버전을 설치 할 수 있습니다.



4.16.0 버전이 설치 되었군요.


그리고 또 다른 변화.

생성된 디렉토리 구조도 변경이 되었습니다.


4.0이상 node_modules 디렉토리 구조를 보면



2.x 대와는 너무 많아서 일부만 가져왔습니다.

, 많은 모듈들이 4.x 대에서는 추가가 되었습니다.

 

이제는 프로젝트를 생성해 볼까요?


>express myProject


뭔가 주르륵 아무 설명도 없이 디렉토리들이 만들어 집니다.

.


고맙게도 하단에 어떻게 하면 테스트가 이루어 지는지 친절하게 설명을 해주고 있네요.


알려주는 방법 그대~로 테스트를 진행 하면 결과를 확인 할 수 있습니다.

 

우선 생성된 프로젝트의 구조와 파일들을 보면




제일 중요한 app.jspackage.json 파일이 하단에 있습니다.

 

하나씩 알려준 순서로 테스트를 진행해 보겠습니다.

 

 Project 가 생성된 directory로 이동하고


     > cd myProject

 

package.json에 있는 dependency를 설치 합니다.


     > npm install



npm install 명령을 실행하면 위에서 설명한 버전별 node_modules 디렉토리가 생성됩니다.




app.js를 이용하여 서버를 띄웁니다.


     > SET DEBUG=myproject:* & npm start



서버가 Port 3000으로 기다리고 있다네요.


지금 만나러 가볼까요?



. 해피엔딩 입니다.


- copy coding -



1. 진동 함수

 

진동 테스트는 무척 단순합니다.

 

진동을 일으키는 방법은 3가지가 있습니다.

 

첫째는 정해진 시간 만큼 한번 작동시키기

 

둘쨰는 정해진 패턴으로 한번 작동 시키기

 

마지막 세번째는 정해진 패턴으로 반복 작동 시키기


입니다.

 

모두 vibrate( ) 함수를 사용하는데 어떤 parameter 를 넘겨 주느냐에 따라

작동법이 달라 집니다.

 

첫번째 한번 작동은 param으로 milliseconds를 넘겨 줍니다.

   vibrate(1000);  // 10001초 입니다.

 

두번째와 세번째는 정해진 패턴의 longmilliseconds의 배열을 넘겨 줍니다.


배열의 형태는

long[] vloop = {0, 500, 100, 500, 100,….}; //5000.5초 입니다.

이고


배열 값의 의미는 {무진동 시간, 진동 시간, 무진동 시간, 진동 시간, ……}

배열 이므로 원하는 만큼 원하는 숫자를 기입하면 됩니다.


그리고 두번째 param에 따라 반복 여부가 결정 됩니다.


-1 이면 1회 진동, 0이상이면 반복 진동입니다.

vibrate(패턴, -1);   //1회 패턴 진동

vibrate(패턴, 0이상); //패턴 반복 진동


그런데 여기서 반복 진동도 2가지 종류로 나누어 집니다.

물론 핸드폰마다 조금씩 다른데, 정상적으로(동일 패턴) 무한 반복하는 것도 있습니다.


함수 사용

 진동 방식

 진동 형태

 vibrate(패턴, -1);

 패턴 1회 진동

 패턴 시간씩 진동/ 종료

 vibrate(패턴, 0);

 패턴 반복 진동

 패턴 시간씩 진동/ 패턴 시간씩 진동

 vibrate(패턴, 1);

 패턴 반복 진동

 패턴 시간씩 진동/ 짧은 시간씩 진동

 vibrate(패턴, 2);

 패턴 반복 진동

 패턴 시간씩 진동/ 패턴 시간씩 진동

 vibrate(패턴, 3);

 패턴 반복 진동

 패턴 시간씩 진동/ 짧은 시간씩 진동

 vibrate(패턴, 4);

 패턴 반복 진동

 패턴 시간씩 진동/ 패턴 시간씩 진동

 ...

  ...

  ...


이런 진동 형태가 반복이 되는데


0, 2, 4, … 짝수의 값은 패턴에 기입한 시간의 패턴이 무한 반복이 되지만


1, 3, 5,… 홀수 값일 경우에는 최초에만 정해진 시간 패턴으로 진동을 하고

그 다음 부터는 매우 짧게 틱, , 틱 하는 정도로만 진동을 합니다.

 


2. 진동 테스트 프로그램

 

2.1 진동 사용 허가


핸드폰의 진동자를 사용하기 위해서는 사용허가를 해야 합니다.


AndroidManifest.xmlpermission을 추가 합니다.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.desk.vibrator">

    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


2.2 Layout 작성

 

기능이 단순해서 vibrate( ) 함수의 parameter 별로 버튼을 만들었습니다.


[1], [패턴 1], [패턴 반복], [종료]


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:text="1초"
        app:layout_constraintBottom_toTopOf="@+id/button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.621" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="48dp"
        android:text="패턴"
        app:layout_constraintBottom_toTopOf="@+id/button3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="48dp"
        android:text="반복"
        app:layout_constraintBottom_toTopOf="@+id/button4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="96dp"
        android:text="종료"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</android.support.constraint.ConstraintLayout>


 

2.3 Main Source

 

Vibrator를 선언하고 버튼을 눌러 진동을 테스트 합니다.

 

추가로 바탕을 터치해도 진동이 되도록 했습니다.


@Override

    public boolean onTouchEvent(MotionEvent event) { }


단순해서 머 더 설명할게 없습니다.


package com.example.desk.vibrator;

import android.content.Context;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn1 = (Button)findViewById(R.id.button);
        Button btn2 = (Button)findViewById(R.id.button2);
        Button btn3 = (Button)findViewById(R.id.button3);
        Button btn4 = (Button)findViewById(R.id.button4);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn3.setOnClickListener(this);
        btn4.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
        long[] vloop = {0, 500, 100, 500, 100, 500, 100};
        if(v.getId() == R.id.button) {
            vibrator.vibrate(1000);  //1초 작동
        } else if(v.getId() == R.id.button2) {
            vibrator.vibrate(vloop, -1); //패턴 1회 작동
        } else if(v.getId() == R.id.button3) {
            vibrator.vibrate(vloop, 0); //패턴 반복
        } else if(v.getId() == R.id.button4) {
            vibrator.cancel();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        final Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
        switch(action) {
            case MotionEvent.ACTION_DOWN :    //화면을 터치했을때 이벤트
                vibrator.vibrate(new long[] {0,100}, 0);  //계속 진동
                break;
            case MotionEvent.ACTION_UP :      //화면을 터치했다 땠을때 이벤트
                vibrator.cancel();  //진동 취소
                break;
            case MotionEvent.ACTION_MOVE :    //화면을 터치하고 이동할때 이벤트
                vibrator.vibrate(new long[] {0,100}, 0);  //계속 진동
                break;
        }
        return super.onTouchEvent(event);
    }
}



3. 결과

 


3.1 결과 화면


버튼과 바탕화면을 클릭 또는 이동 하면서 테스트 하세요.


android vibrator sensor


3.2 Source Code

 

 

Vibrator.7z



3.3 APK File


Vibrator.apk


- copy coding -


Android studio version 3.1.4를 다운 받아 새로 설치하고 android studio에서 프로젝트를 만들면 레이아웃 미리보기에서 hellow world가 안보이는 형상이 발생 했습니다.


그뿐만 아니라 다른 컴포넌트를 추가해도 역시 안보입니다.


androdi studio render problem


실행을 하면 AVD에서는 잘 보이는데…



 

에러가 있다고 표시가 있네요.


열어보니 Render problem인데 모르는 에러라고???

어떻게 하라고?

 

구글링을 하니

 

styles.xml에 들어가서 테마에 Base를 추가하면 된다고 하네요.


수정을 해보니 잘 되긴 하는데

 


매번 이렇게 하라고?

 

구글 지들은 알고 있겠지.” 하고 찾아보니


알고 있네! 알고 있어!



걍 업데이트가 답이라네요.


알려준데로 Help > Check for updates를 합니다.



창이 뜨면서 업데이트 하던가 말던가 두가지로 물어보지 뭘 저리 많이 물어보는지.




업데이트 하고 재시작 [Update and Restart] 버튼을 클릭 합니다.

 

한참을 진행합니다.



재시작 하면서 또 멀 물어보네요.



귀찮다. 그냥 [OK]

 

과연 결과는~~~~!



이것도 한참 돌아가네…… 내가 돈다돌아



쉽지 않군요.


이번에는 Gradle plugin update




또 한참을 기다립니다.



~! 잘 되는 군요.

 

버전은 같은데 build 버전이 최신입니다.



- copy coding -


node 내부에는 기본적인 프로그램을 할 수 있는 기능들이 있습니다.

최초 설치시 기본적인 모듈들도 같이 설치가 되지만 좀더 풍부한 기능을 사용 하려면

외부에 있는 모듈을 추가로 설치 해야 합니다.


사용되는 모듈이 많아지면 하나씩 수작업으로 관리하기가 어려워집니다.

만약에 버전도 관리를 해야 한다면 상당히 귀찮아 질 수 있는데

node.js에는 이런 걱정을 덜 수 있는 npm(Node Package Manager)이라는 툴이 있습니다.


npmpackage.json라는 파일을 이용하여 프로젝트에 필요한 모듈들을 관리 합니다.

java에서 maven으로 프로젝트를 관리할 때 pom.xml 파일을 작성하는 것과 비슷합니다.


nodejs npm


npm을 사용하는 명령어 몇개를 보면


- 모듈 설치 방법


>npm install [패키지명]

>npm install [패키지명]@[버전]

>npm install [패키지명]@”<2.1”   -- 버전이 2.1 보다 작은 것

 

- 모듈 제거 방법


>npm uninstall [패키지명]

 

- 모듈 업데이트 방법


>npm update [패키지명]


 

이런식으로 작업을 합니다.

만약 프로젝트에 설치할 모듈이 많아지면 수작업으로 하기는 어렵겠죠?

그래서 package.json 이라는 파일을 이용해 관리를 하면 편리 합니다.


{
  "name": "Test",
	"version": "0.0.1",
	"dependencies": {
	   “express” : “4.16.4”
	   “jade” : “*”
	}
}

이렇게 package.json 파일의 dependencies 내부에 필요한 모듈을 작성한 후


>npm install


>npm update


하기만 하면 명시된 모듈들이 모두 인스톨 되거나 업데이트가 됩니다.

 

간단하게 테스트를 해보겠습니다.

물론 위에서 처럼 수작업을 하지는 않고 eclipse에서 작업을 합니다.


파일을 하나 만들고 실행을 해봅니다.




var express = require('express');

 

express 라는 모듈이 최초 node 설치파일에 포함되지 않아 오류가 발생하는군요.

 

npm을 초기화 해보도록 하겠습니다.



프로젝트(Test)에서 마우스 우측 버튼을 클릭 > New > Other…



npm Init



[Next] 버튼을 누릅니다.



[Finish]버튼을 누릅니다.

 

그러면 좌측에 못보던  package.json 이라는 파일이 생겼네요.



프로젝트에 대한 전반적인 환경을 포함하고 있는 파일입니다.


이제 설치할 모듈을 추가할 수 있게 되었습니다.


package.json 파일에 express와 버전을 기입 합니다.


"dependencies": {

    "express": "4.16.3"

}




npm을 이용하여 패키지를 추가해 줍니다.



 

디렉토리에는 어떤 변화가 있을까요?

 

npm Install을 하기 전 모습



npm Install을 실행 후 모습



node_modules 디렉토리가 새로 생성 되었습니다.

 

node_modules 디렉토리 구조를 볼까요?



너무 많아 일부만 담았습니다.

 

node_modules 하위에 무척 많은 디렉토리가 생성이 되었습니다.

 

express 4.x 버전부터 변화가 생겼습니다.

 

4.x 버전 이전의 node_modules 하위 디렉토리 구조는

 



이렇게 몇 개 되지 않았는데 좀더 많은 기능들이 추가 되었습니다.


이제 프로그램을 실행 합니다.



잘 실행이 되고 있군요.


서버가 기동하고 Client의 접속을 기다리고 있습니다.


웹브라우저를 하나 열어 접속을 시도해 봅니다.


http://localhost:8181/



성공입니다.



이것도 동일한 결과죠.


 


몇줄 되지 않지만 웹서버의 역할을 하고 있습니다.

서버는 계속 대기상태에 있습니다.


만일 동일한 포트를 사용하거나 수정을 하고 다시 테스트를 하는 경우에는

기존 웹서버를 내리고(프로세스 종료) 테스트 합니다.



기존 서버가 살아있으면 포트를 사용할 수 없어 오류가 발생 합니다.


- copy coding -


1···110111112113114115116···118

+ Recent posts