[Android] NanoHTTPD로 안드로이드 앱에서 웹서버 구현하기

앱에서 웹서버를 구현할 수 있다고??!

NanoHTTPD란?

자바를 사용하는 플랫폼에서 HTTP서버를 만들 수 있는 오픈소스 라이브러리입니다.

NanoHTTPD의 원리는?

자바의 ServerSocket으로 요청을 받아들이고 한 Socket 에 스레드를 만들어 처리 하는 방식으로 이루어져 있습니다. 안드로이드도 자바를 사용하기 때문에 NanoHTTPD를 사용하여 앱에서 웹서버를 구현할 수 있습니다.


구현 방법

1-1. 클래스 생성

먼저 NanoHTTPD를 extends 받는 WebServer클래스를 만들어 주고 로그에 사용할 TAG와 Port를 상수로 선언해줍니다.

public class WebServer extends NanoHTTPD {
	private static final String TAG = WebServer.class.getSimpleName(); // 로그에 사용할 TAG
    private static final int PORT = 8080; // 포트번호
}

1-1. 싱글톤으로 객체 생성

이후에 생성자와 웹서버 객체를 가져오는 getServer() 함수를 만들어 줍니다. 싱글톤 패턴으로 구현하였습니다.

private WebServer() throws IOException {
        super(PORT);
    }
    public static WebServer getServer() throws IOException {
        if(server == null){
            server = new WebServer();
        }
        return server;
    }

2. 클라이언트 요청 처리 함수 구현

이후에 클라이언트의 요청을 받는 serve() 함수를 오버라이드 받습니다.
이 부분에서 클라이언트의 요청을 받아 처리를 하고 클라이언트에게 Response를 리턴합니다.

@Override
    public Response serve(IHTTPSession session) {
    	Map<String, String> headers = session.getHeaders(); // 세션의 헤더
        Method method = session.getMethod(); // 세션의 메소드
        String uri = session.getUri(); // 세션의 Uri

        Map<String, List<String>> decodedQueryParameters = decodeParameters(session.getQueryParameterString());
    }

위에서 보면 IHTTPSession session 을 파라미터로 받는데 이 session 안에는 Http 세션의 Header, Method, Uri등을 가지고 있습니다.

✔ 이때 decodedQueryParameters에는 헤더의 토큰이 들어있습니다.

이전에 작성한 RestAPI를 보면 클라이언트에서 어떤식으로 요청하는지 볼 수 있는데
Retrofit2에서 작성한 interface로 한 가지 예를 들어보면

@POST("posts/post")
  • Method: Get, Post, Patch, Put, Delete 등이 있습니다. 위의 코드에서 POST가 이 부분에 해당합니다.
  • Uri: BaseUrl 뒤에 붙는 EndPoint를 말합니다. 위의 코드에서 "posts/post"가 이 부분에 해당합니다.

이 Method와 Uri로 클라이언트의 요청에 따라 처리할 수 있습니다.

📌Method가 POST 일때는 Body를 파싱 해야 합니다.

Map<String, String> map = new HashMap<String, String>(); // Body를 넣을 Map 선언
session.parseBody(map); // 세션의 Body를 map에 파싱

위와 같이 Body를 담을 Map을 선언하고 session.parseBody(map); 함수로 파싱합니다.

3. 클라이언트에 보낼 Response 구현

Response는 클라이언트의 요청을 성공과 실패(실패시 여러가지 에러 메세지 처리)결과에 따라 리턴 해주는 객체입니다.
구현 방법은 다음과 같습니다.

성공시

return newFixedLengthResponse(Response.Status.OK, "application/json", "정상적으로 처리 되었습니다.");

이때 Response.Status.OK 는 서버에서 보내는 메세지로 코드 200 입니다.

실패시

return newFixedLengthResponse(Response.Status.BAD_REQUEST, "application/json", "잘못된 요청입니다.");

이때 Response.Status.BAD_REQUEST는 우리가 자주 볼 수 있는 메세지죠 코드 400 입니다.
이런식으로 Response.Status. 에는 많은 서버 리스폰스 코드가 구현 되어있습니다.
상황에 따라 에러처리나 성공 처리를 보내도록 구현하면 됩니다.

이렇게 NanoHTTPD를 사용하면 안드로이드 앱에서도 서버를 구현할 수 있습니다! 😲👍


이번에 NanoHTTPD를 공부하면서 HTTP서버에 대해 많은 지식을 얻을 수 있는 기회가 된 것 같습니다.

Reference

NanoHTTPD 깃허브

좋은 웹페이지 즐겨찾기