(24)

[사이드 프로젝트] 운동 기록앱 "오운완" 제작기 - 1

어느덧 30이 되어가는 나이에, 2년 가까이 공부를 핑계로 몸관리에 소홀해졌다.어디가서나 얘기하는 사소한 것도 기록하는 습관이 장점이에요!!! 는 살다보니 기록하지 않으면 수행하지 않는다. 가 되어버렸다.2년 내내 헬스장에 등록은 되어 있었으나, 관장님들이 가장 좋아하는 스타일(?)인 유령회원이 되어버렸다. 1달에 1번 갈까말까.. 내가 직접 만든 기록 서비스를 사용하면 더 열심히 운동할 것만 같았고직접 헬스장에서 운동을 하면서 기록을 하기 위해 모바일 앱으로 가닥을 잡고 작업을 시작하게 되었다. 3월 중순부터 1달 반 정도의 제작 기간을 거쳐 작업했고, 현재는 어떤 이슈들 때문에 릴리즈 전 단계에서 테스트중인나의 첫 애플리케이션에 대해 간단하게 기록하고 나아갈 방향에 대해 서술해보고자 한다. 더보기  ..

웹뷰로 기존 NextJS를 모바일 앱으로 배포하기

초년차 백엔드 개발자의 사이드 프로젝트 앱 배포 경험기입니다.(기술적 서술이 없습니다.) NextJS로 구성된 웹앱을 React Native + Expo를 사용해 안드로이드 앱으로 전환하고 배포하는 과정의 기록입니다.(기본 도메인 세팅이 완료되었고, Vercel로 배포해놓은 상태입니다.)    개발서버기존 NextJS로 구성된 프론트를 React Native로 EXPO를 통해 테스트용 APK를 만들어보기로했음.  expo-cli는 deprecated되었고, node 17v 이상과 호환성 문제가 발생할 수 있다고 합니다.프로젝트 내 자체 cli를 설치하여 사용하는 걸 권장한다고 합니다.expo build명령어도 eas build로 대체되었다고 하네요# expo cli 설치npm install expo-cl..

멜론 플레이리스트 유튜브 뮤직 재생목록으로 옮기기 with NodeJS, Selenium

개발 동기 유튜브 프리미엄이야 그렇다쳐도, 멜론을 처음 스트리밍클럽에 가입했던게 2010년도 초반쯤이었다. 그때는 분명 3천원이었던걸로 기억하는데... 하기사 체감 물가가 김밥 한줄에 천원하던 시대에서 3~4천원하니 그럴만도 하다 싶지만, 돈을 좀 아껴보고자 멜론 구독을 이제 보내줄 때가 된 것 같다. 가수 - 노래제목 형태의 CSV파일로 파싱해서 soundiiz 로 유튜브 뮤직 플레이리스트를 만들어 줄 수 있다고 한다. 나는 이제 개발자이기도 하니까, 직접 해보기로했다. 오랜만에 셀레니움도 다시 써볼겸 작업을 했는데, 여전히 셀레니움으로 구글 플랫폼을 핸들링하는 데 짜증이낫다. 구글 로그인과정에서 오래 잡아먹어서 한 7~8시간정도 걸렸다. 작업물 GitHub - mag123c/from-Melon-to-..

[AWS] AWS에서 도메인 구매하고 서버와 연결하기 / Route 53 HTTPS(SSL) 리다이렉트

도메인 구매 https://us-east-1.console.aws.amazon.com/route53/v2/home?region=us-east-1#Dashboard https://us-east-1.console.aws.amazon.com/route53/v2/home?region=us-east-1#Dashboard us-east-1.console.aws.amazon.com AWS의 Route 53d Dashboard에서 Domain registration에서 도메인을 등록해준다. 원하는 도메인네임을 검색하면 아래와 같이 사용 가능 여부, 추천 도메인이 나온다. 원하는 걸로 등록하자. 등록하면 본인의 메일로 Verify 메일을 보내준다. 반드시 해당 메일에서 인증을 진행해야 등록 절차가 진행된다. 나는 점심식..

GitHub Actions을 사용하기 위한 Token 발급 방법

현재 프로젝트 환경이 docker - gitactions을 통한 CI/CD구축이 되어 있어 너무 생소했다. 실습 겸 새로 프로젝트를 하나 생성하여 CI/CD를 구축해 볼 계획이다 그러기에 앞서 Token을 발급해보자 발급 방법 1. Settings - Developer Settings Settings에 들어가서 최하단에 Developer Settings에 들어간다. 2. Personal access tokens 에서 Generate new token 토큰 발급을 해준다. workflow, write, delete권한은 주어야 한다. [Feedback tracking] Fine-grained personal access tokens · community · Discussion #36441 This topi..

[SpringBoot] 대량의 데이터를 어떻게 다루어야 할까

서론 ★혹시 좋은 의견이 있으시다면 댓글로 좀 알려주시면 감사하겠습니다.. 초보 개발자에게 한줄기 빛을.. 토이 프로젝트의 방향이 결국 리그오브레전드 챔피언들의 모의 투자 로 방향성이 잡혔다. https://developer.riotgames.com/docs/lol Riot Developer Portal League of Legends Developer API Policy Before you begin, read through the Terms of Use and Legal Notices. Developers must adhere to policy changes as they arise. When developing using the API, you must abide by the following: P..

[IntelliJ] IntelliJ와 Github 연동

IntelliJ Git 설정 Git 경로 설정 File - Settings - Git에서 깃 경로 설정 보통은 설치하면 자동으로 경로가 잡히는데, 깔려있지 않다면 Git을 설치하고 재시도 해보자. GitHub 계정 연동 Add account 클릭 - Log in via GitHub 클릭 클릭하면 GitHub 로그인 - JetBrains에 권한 부여 후 연동이 완료됨 프로젝트 Git 연동 1. VCS - Enable Version Control Intergration 클릭 후 아래 화면처럼 나오면 OK 버튼 클릭 2. Git - Manage Remotes - Repository 주소 입력 3. Project 우클릭 - Git - Pull 진행 진행 시 빨간 색으로 없는 branch라고 나타날 시, Ctrl..

검수 및 보수) 회원가입 - Spring Project(OTT Service)

이전 글 목록 1) 주어진 RFP를 바탕으로 주제 선정 - Spring Project(OTT 서비스) 2) ERD 설계 - Spring Project(OTT 서비스) 3) 회원 가입 기능 구현 - Spring Project (OTT 서비스) 4) 로그인, 로그아웃 기능 구현 - Spring Project (OTT 서비스) 5) 상세 페이지 및 회원 정보 수정 - Spring Project (OTT 서비스) 6) CRUD를 한번에 → 게시판 만들기(QNA게시판) - Spring Project(Mybatis) (OTT 서비스) 7) 게시판 페이징 처리 - Spring Project (OTT 서비스) 8) 카카오 지도 API 사용하기 - Spring Project (OTT 서비스) 9) (네아로) 네이버 로그..

16) 웹소켓(WebSocket)을 활용한 댓글 답글(대댓글)알림 - Spring Project(OTT Service)

해당 프로젝트는 2023/01/25 ~ 2023/03/12 내에 진행되는 아카데미 내 수강생들끼리 팀을 나누어 진행한 모의 프로젝트입니다. 팀원은 6명이었으며, 프로젝트 리더를 맡았습니다. 이전 글 목록 1) 주어진 RFP를 바탕으로 주제 선정 - Spring Project(OTT 서비스) 2) ERD 설계 - Spring Project(OTT 서비스) 3) 회원 가입 기능 구현 - Spring Project (OTT 서비스) 4) 로그인, 로그아웃 기능 구현 - Spring Project (OTT 서비스) 5) 상세 페이지 및 회원 정보 수정 - Spring Project (OTT 서비스) 6) CRUD를 한번에 → 게시판 만들기(QNA게시판) - Spring Project(Mybatis) (OTT 서..

[사이드 프로젝트] 운동 기록앱 "오운완" 제작기 - 1

삽질/사이드 프로젝트 2024. 5. 20. 14:33
728x90
728x90

 

어느덧 30이 되어가는 나이에, 2년 가까이 공부를 핑계로 몸관리에 소홀해졌다.

어디가서나 얘기하는 사소한 것도 기록하는 습관이 장점이에요!!! 는 살다보니 기록하지 않으면 수행하지 않는다. 가 되어버렸다.

2년 내내 헬스장에 등록은 되어 있었으나, 관장님들이 가장 좋아하는 스타일(?)인 유령회원이 되어버렸다. 1달에 1번 갈까말까..

 

내가 직접 만든 기록 서비스를 사용하면 더 열심히 운동할 것만 같았고

직접 헬스장에서 운동을 하면서 기록을 하기 위해 모바일 앱으로 가닥을 잡고 작업을 시작하게 되었다.

 

3월 중순부터 1달 반 정도의 제작 기간을 거쳐 작업했고, 현재는 어떤 이슈들 때문에 릴리즈 전 단계에서 테스트중인

나의 첫 애플리케이션에 대해 간단하게 기록하고 나아갈 방향에 대해 서술해보고자 한다.

 

더보기

 

 

애플리케이션 구성

많은 개발자들이 말하는 JavaScript의 장점 중 빠른 개발을 체감해보고자 프론트는 Next로, 백엔드는 Nest로 구성했다.

백엔드를 Nest로 구성한 이유는 Node위에 기본적인 ORM, Auth, 소셜로그인에 대한 부분들을 좀 더 편하게 사용하기 위해서였다.

 

프론트는 Vercel, 백엔드는 AWS EC2에 배포되어 있으며

모바일 애플리케이션은 WebView를 사용하여 URL을 바인딩하고, EAS(Expo)를 활용하여 IOS, Android용으로 빌드 및 배포하였다.

 

 

 

 

1.

필요 시 개발 컨테이너를 올려서 테스트를 했다.

프로젝트 내에서는 이미지 I/O 작업에서, 실제 서버 도메인을 필요로 했었기 떄문에 해당 경우에 사용하였다.

 

2.

AWS 과금 줄이기 포스팅 에서의 경험을 토대로, 나의 경우에서는 

ALB에서 Nginx에 대한 트래픽 분산 처리를 하지 않기 때문에 ALB는 사용하지 않았다

기존 ACM을 통한 SSL인증 처리를 Nginx로 이전하고, 로드밸런싱 또한 차후에 필요 시 컨테이너의 대수를 늘려 사용할 계획이다.

 

3.

백엔드 컨테이너는 무중단 배포를 Git Action의 Workflow를 통해 구축했으며, 헬스 체크를 통한 백업 컨테이너로의 restore가 적용되어 있다.

 

4.

필요한 로그들은 Discord Webhook을 통해 개인 채널에 메세지 형태로 받아볼 수 있게 구성하였다.

 

 

 

 

진행상황

나를 위한 기록 어플을 타겟으로 삼았기 때문에, 우선 내가 중점적으로 필요한 체중과 운동기록 부분만 우선적으로 구현했다.

 

간단하게 소셜 로그인을 거치고나면, 운동과 체중을 기록할 수 있게 구성했다.

앱 아이콘은 미리캔버스에서 사각형 크기와 색상을 변경해가며 덤벨 아이콘으로 제작했고

디자인 부분은 관련 분야에서 이미 많은 사용자를 보유하고 있는 PLANFIT, FLEEK을 보고 영감을 얻어 제작했다.

(자세하게 보고 싶다면 위의 앱 이미지 보기를 클릭해보길)

 

 

 

비용 문제

작업을 완료하여 베타버전을 릴리즈하여, 사용자를 조금이라도 더 다양하게 모아 테스트를 받아보고 싶었으나 과금 요소들이 많이 부담이 되었다.

 

첫 번째로, 애플리케이션 릴리즈를 위한 개발자 계정의 과금 문제다.

찾아본 바로는 앱을 릴리즈하기 위해서, 안드로이드, IOS 진영 각각의 개발자 계정을 등록해야하는데

안드로이드는 25달러(최초) , 애플은 99달러(연간)가 발생한다고 했다.

 

 

 

두 번째로, 또, 앱에서 사용하는 운동 이미지에도 과금적인 요소가 추가될 수 있었다.

(결론적으로 계산을 해보니,300달러정도가 필요했다.)

 

운동 동작별로 운동 수행동작과 타겟부위를 보여줄 수 있는 이미지를 반드시 추가하고 싶었고, 찾아보니 LYFTA라는 앱의 이미지를 사용해보고 싶었다.

 

귀사의 운동 이미지를 비상업적인 단순 운동 기록을 위해 사용할 것인데 사용 가능한지? 아니라면 얼마의 금액을 부과해야하는지, 혹시 귀사의 이미지가 아니라면 출처가 어디인지? 와 같은 질문을 메일로 보냈고, 감사하게도 출처를 받아볼 수 있었으며 직접 해당 이미지의 판매처와 연결도 해주었다.

 

 

 

 

대량 구매 시 할인을 제공해준다고 했지만, 개발자 계정과 이미지 가격을 합쳐 4~50만원이 넘는 돈이 필요했다.

현재로서는 많이 부담이 되었다.

 

 

과금적인 문제들로 인해 현재는 지인들에게만 직접 apk, ipa파일을 제공하여 10명 남짓한 베타 테스터를 보유한(?) 서비스를 운영중이다.

 

 

 

테스트 개선사항

테스터(?)들 덕분에 추가 요청사항이나, 개선 사항들을 모아볼 수 있었다.

 

1.

앱 스플래시 이미지가 없어진다.

웹뷰로 NextJS를 바인딩할 때(포스팅), 스플래시 이미지 관련 코드도 추가했는데 이 부분에서 문제가 발생한 것 같다.

현재 증상은 스플래시 이미지는 등장하자마자 사라지고, 흰 화면이 설정한 3초동안 렌더링된다고 한다.

 

2.

자주 사용하는 운동의 그룹화가 필요하다.

"나 3분할하는데 루틴 돌 때마다 계속 새로 추가해야해 ㅡㅡ, 루틴 저장했다가 불러올 수 있게 해줘" 라는 요청을 받았다.

나는 해당 부위 운동을 할 때도 순서를 계속 바꿔가면서 운동하기 때문에 상관없다고 판단했지만, 자주하는 운동을 묶어서 바로 가져올 수 있게 기능을 추가할 필요가 있겠다는 생각이 들었다.

 

3.

식단은?

내 애플리케이션의 정체성은 운동과 체중에 대한 것만 기록하기로 했었다. 이건 좀 차후에 생각해보기로 했다.

 

4.

디자인이 구려

미.....미안해 ㅠㅠ 이건 어쩔 수 없어...

 

 

 


 

이번 프로젝트를 만들어가면서, 개발의 속도와 효율성에 대해 생각해보았다. 

짬짬이 개발을 했기 때문에 전체 개발에 어느정도 시간을 잡아먹었다.

하지만 하나의 기능을 개발할 때 프론트, 백엔드 모두 공통의 언어로 빠르게 개발할 수 있었다. 이것이 자바스크립트의 장점인가!!!

 

 

생각보다 앱 하나를 배포하는데, 과금적인 요소를 무시할 수 없는 거구나. 특히 개인 프로젝트는 더 부담스럽게 다가왔다.

회사에서는 과금 요소보다는 성능 최적화와 좋은 코드 작성에 더 집중하게 되지만, 이번 경험을 통해 과금 요소까지 고려할 수 있는 개발자가 되는 게 더 좋은 개발자가 되는 길일 것 같았다. 앞으로의 개발이 더 재밌어질 것 같다.

 

테스터들의 개선 사항을 반영하고, 요구 사항을 어느정도 맞춰가면서 최대한 과금적인 요소를 줄일 수 있는 방향으로 릴리즈하는 것을 목표로 달려나가야겠다.

 

조금 더 보완해서, 릴리즈 후의 경험을 조금 겪고 관련된 포스팅으로 돌아오겠습니다. 감사합니다!

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

웹뷰로 기존 NextJS를 모바일 앱으로 배포하기

삽질/사이드 프로젝트 2024. 4. 30. 13:56
728x90
728x90

출처: 위키미디어

 
 
 
초년차 백엔드 개발자의 사이드 프로젝트 앱 배포 경험기입니다.
(기술적 서술이 없습니다.)
 
NextJS로 구성된 웹앱을 React Native + Expo를 사용해 안드로이드 앱으로 전환하고
배포하는 과정의 기록입니다.
(기본 도메인 세팅이 완료되었고, Vercel로 배포해놓은 상태입니다.)
 
 
 
 

개발서버

기존 NextJS로 구성된 프론트를 React Native로 EXPO를 통해 테스트용 APK를 만들어보기로했음.
 
 
expo-cli는 deprecated되었고, node 17v 이상과 호환성 문제가 발생할 수 있다고 합니다.
프로젝트 내 자체 cli를 설치하여 사용하는 걸 권장한다고 합니다.
expo build명령어도 eas build로 대체되었다고 하네요

# expo cli 설치
npm install expo-cli

# expo project 생성
expo init APKTest
cd APKTest

# 네이티브 웹뷰 설치
expo install react-native-webview

 
 
App.js의 코드를 아래와 같이 수정하고
 
 
 

//App.js
import React from 'react';
import { WebView } from 'react-native-webview';

export default function App() {
  return <WebView source={{ uri: 'https://your-nextjs-app.com' }} style={{ marginTop: 20 }} />;
}

 
 

npx expo start

 
이제 다됐으니 개발서버를 실행시켜본다.
 

 
 
OS에 맞는 Expo를 설치하고
(Android: Expo)
(IOS: Expo Go)
 
QR코드를 찍으면 아래와같이 게이지바가 올라가며, 빌드 되는것을 볼 수 있음

 

QR 스캔 시 반드시 같은 로컬 네트워크여야 한다.
 
 
 
 
아래 코드는, 안드로이드의 뒤로가기버튼 기능과(안하면 바로 종료됨)
모바일 상태표시줄을 앱이 삼켜버리는, 가려버리는 것을 해결하기 위한 간단한 기능들을 적용한 코드다.

(IOS, Android에 따라 다른 코드들이 좀 있나보다)

import SplashScreen from 'expo-splash-screen';
import React, { useEffect, useRef, useState } from 'react';
import { BackHandler, View } from 'react-native';
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import { WebView } from 'react-native-webview';

async function delaySplash() {
  try {
    await SplashScreen.preventAutoHideAsync();
    await sleep(3000);
  } catch (e) {
    console.warn(e);
  } finally {
    await SplashScreen.hideAsync();
  }
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

const App = () => {
  const webviewRef = useRef(null);
  const [canGoBack, setCanGoBack] = useState(false);

  useEffect(() => {
    delaySplash();
  }, []);

  useEffect(() => {
    const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
      if (canGoBack) {
        webviewRef.current.goBack();
        return true;
      } else {
        BackHandler.exitApp();
      }
      return false;
    });

    return () => backHandler.remove();
  }, [canGoBack]);

  return (
    <SafeAreaProvider>
      <AppContent webviewRef={webviewRef} canGoBack={canGoBack} setCanGoBack={setCanGoBack} />
    </SafeAreaProvider>
  );
};

const AppContent = ({ webviewRef, canGoBack, setCanGoBack }) => {
  const insets = useSafeAreaInsets();

  return (
    <View style={{ paddingTop: insets.top, paddingBottom: insets.bottom, backgroundColor: '#343a40', flex: 1 }}>
      <WebView
        ref={webviewRef}
        source={{ uri: 'https://app.ounwan.net' }}
        onNavigationStateChange={(navState) => setCanGoBack(navState.canGoBack)}
      />
    </View>
  );
};

export default App;

 
 
 
 
 
 

APK 빌드

실제 빌드를 해보기로 했음..
 

expo build:android (x)
npx expo build:android (x)

 
위에서도 언급했듯이, build 명령어가 교체되어 사용이 안된다.

# 택일
npm install -g eas-cli
eas build --platform android

npm install --save-dev eas-cli
npx eas build --platform android

 
빌드를 진행하게되면, 이메일과 패스워드를 물으니 Expo에 가서 회원가입을 하자.
 

 

 
잠시 기다리니 빌드가 완료되었으며, Expo에서 확인할 수 있었다.
배포는 됐으나 expo doctor?? 여기서 뭔가 경고가 발생했다.

 

 
expo-permission이 사용자의 위치, 연락처와 같은 민감한 정보에 편하게 엑세스하기위해 사용한다고 되어있는데
버전 충돌이 일어나기도 하고, 필요없을 것 같아 삭제해주었다.
 
위의 경고창에서 안내된것처럼 check를 하였더니
알아서 모듈 업그레이드나 다운그레이드 및 삭제와 같은 작업들을 진행해주었다.

 

 
로컬에서 의사선생님(?)을 다시 불러서 문제없음을 확인했고

 
 

 
 
APK가 정상 배포됨을 확인할 수 있었다.
 
 
 
 
 
 

IPA 빌드

eas build --platform ios

 
IOS는 애플 ID를 묻는다.
그리고 애플 개발자 계정이 있어야하니 가입해주자.
 
가입할때, 애플쪽은 개발자계정 등록을 위해 과금까지 마쳐야하는 것 같던데,
13만원 결제하라고 되어있어서, 빌드는 살포시 접어두었다.
프리티어 같은게 있는 것 같은데, 개인 개발자는 불가능하다고해서 여기까지....
 
 

 

Apple Developer Program 연회비 면제 - 지원 - Apple Developer

포럼 Apple 엔지니어 및 다른 개발자에게 개발 주제에 관해 질문하고 이야기를 나눌 수 있습니다. 포럼 보기(영문)

developer.apple.com

 
 
 
 
 

기타(개발자 계정 가격)

 

 
 
 
 
 
 

마무리

많이 헤맬 줄 알았는데 생각보다 엄청 빨리 마무리된 것 같다.
 
실제 앱을 배포하는게 목적인데
프로젝트 주제에 맞게, 운동을 좋아하는 지인분들께 공유드려보고
전반적인 서비스의 문제점들을 수정, 보완하여 꼭 배포까지 사이클을 돌려
실제 서비스에서 발생하는 이슈들에 대응해봐야겠다.
 
실제 서비스 후 이슈들에 대응하는 글로 돌아올 수 있길!!
 
 
 
 
 
 

참조

 

Troubleshoot build errors and crashes

A reference for troubleshooting build errors and crashes when using EAS Build.

docs.expo.dev

 

Expo build failed for android

I'm building a react native app that is using the ble plx library. For that I think it got ejected. Now I'm trying to publish a internal test in the google play store. I ran the command expo build -p

stackoverflow.com

 

Build error after updating to 5.2.10 · Issue #7981 · react-navigation/react-navigation

Current Behavior updated @react-navigation/bottom-tabs, native, stack to latest version just now. Getting above error. Already tried deleting the cache, but no luck Your Environment software versio...

github.com

 

[앱만들기] 웹개발자가 가장 쉽게 어플만들기③ (EXPO로 AFK 만들기)

준비 앞전 구름 IDE를 통해 NodeJS React Native Expo 개발환경을 구축했으며, Expo를 통해 내가 제작할 어플리케이션을 미리보기로 확인했습니다. 이번에는 미리 본 어플리케이션을 실제 APK로 변환해보

tyrannocoding.tistory.com

 

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

멜론 플레이리스트 유튜브 뮤직 재생목록으로 옮기기 with NodeJS, Selenium

삽질/사이드 프로젝트 2024. 4. 14. 00:13
728x90
728x90

 

 
 

개발 동기

 
유튜브 프리미엄이야 그렇다쳐도, 멜론을 처음 스트리밍클럽에 가입했던게 2010년도 초반쯤이었다. 그때는 분명 3천원이었던걸로 기억하는데... 하기사 체감 물가가 김밥 한줄에 천원하던 시대에서 3~4천원하니 그럴만도 하다 싶지만, 돈을 좀 아껴보고자 멜론 구독을 이제 보내줄 때가 된 것 같다.
 

 
 

 
 
가수 - 노래제목 형태의 CSV파일로 파싱해서 soundiiz 로 유튜브 뮤직 플레이리스트를 만들어 줄 수 있다고 한다.
 
나는 이제 개발자이기도 하니까, 직접 해보기로했다. 오랜만에 셀레니움도 다시 써볼겸 작업을 했는데, 여전히 셀레니움으로 구글 플랫폼을 핸들링하는 데 짜증이낫다. 구글 로그인과정에서 오래 잡아먹어서 한 7~8시간정도 걸렸다.
 
 
 

작업물

GitHub - mag123c/from-Melon-to-YTMusic

Contribute to mag123c/from-Melon-to-YTMusic development by creating an account on GitHub.

github.com

 
작업물은 위 레포에서, 간단한 영상과 함께 확인할 수 있다.
로컬 실행을 위해 NodeJS위에서 작업했고, Selenium을 사용했다.
 
구글 로그인이 자동화된 브라우저에서 동작하지 않아, 로컬의 Chrome.exe를 직접 실행해서 셀레니움이 실행시킨 크롬을 핸들링하게 동작한다.
 
옛날에 크롤러를 제작할 때, Java Swing으로 UI를 간단하게 만들고 exe로 배포해서 사용했던 기억이 나서, ID / PW를 콘솔에 입력하고, 동작과정을 출력받는 I/O를 자바 스캐너처럼 prompt-sync를 사용해서 구현했는데, 딱히 UI를 만들지는 않았다.
 
희한한 것은, 유튜브 뮤직이 요근래 멜론을 따잇(?)했다는 기사를 본 적이 있는데, 생각보다 정확하지 않았다는 점이다.
예를들어 비비 - 밤양갱 처럼 검색을 하면 다른 곡이 가장 최상위에 있는 경우가 더러 있다. 물론 밤양갱이 그렇다는 건 아니지만, 검색 결과의 정확도가 90%정도 되는 것 같았다.
 
 
사용방법은 레포 Readme에 기술되어 있듯이 클론 후 주의사항이나 선수행 동작을 잘 숙지한 후 실행만 하면 된다.
 


10년 넘게 계속해서 업데이트하며 사용하던 멜론 플레이리스트를 옮기는 작업을 끝냈다.
아쉽지만 멜론과는 이제 작별이다. 안녕..

 

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

[AWS] AWS에서 도메인 구매하고 서버와 연결하기 / Route 53 HTTPS(SSL) 리다이렉트

삽질/사이드 프로젝트 2023. 9. 27. 20:32
728x90
728x90

 

 

도메인 구매

https://us-east-1.console.aws.amazon.com/route53/v2/home?region=us-east-1#Dashboard 

 

https://us-east-1.console.aws.amazon.com/route53/v2/home?region=us-east-1#Dashboard

 

us-east-1.console.aws.amazon.com

 

AWS의 Route 53d Dashboard에서 Domain registration에서 도메인을 등록해준다.

 

원하는 도메인네임을 검색하면 아래와 같이 사용 가능 여부, 추천 도메인이 나온다. 원하는 걸로 등록하자.

 

 

등록하면 본인의 메일로 Verify 메일을 보내준다. 반드시 해당 메일에서 인증을 진행해야 등록 절차가 진행된다.

나는 점심식사 전에 인증을 진행하고 점심먹고 오니 등록이 완료되었다.

 

 

 

 

호스팅 영역 설정

AWS에서 도메인을 구매하면 자동으로 호스팅 영역이 지정된다.

아래의 호스팅 영역에서, 이름을 클릭한다.


레코드 생성을 눌려, 값에 본인의 EC2 public IPv4를 입력한다. 레코드 네임은 www와 같은 레코드를 작성하면 www.test.com과 같은 경로로 접속이 가능하다.

 

 

 

ACM(AWS Certificate Manager) 생성

ACM에서, 인증서 요청을 진행한다.

본인의 도메인 네임을 작성하면 된다.

 

요청 후, 인증서 상태에서, Route 53 레코드 생성을 진행하자.

 

들어가면 자동으로 연결되는 레코드가 있다. 연결을 완료하고 호스팅 영역에 가면 아래와 같은 CNAME이 생성되어 있다.

 

 

 

대상 그룹 생성

EC2의 네비바에서 하단에 대상 그룹 생성을 클릭하자.

대상 그룹 이름만 지정한 뒤 다음 버튼을 클릭했으며

 

 

다음 탭에서는 보류중인 것으로 포함을 선택했다.

 

애플리케이션 로드 밸런서(ALB) 생성

마찬가지로 EC2의 네비바에서, 로드밸런서 탭을 들어가서 생성해준다.

 

애플리케이션 로드 밸런서를 선택한 후, 아래의 화면에서 본인의 EC2의 네트워크를 반드시 포함하여 두 개를 선택해야 한다.

 

리스너 및 라우팅 탭에서 아까 생성했던 대상 그룹을 선택하자. SSL 적용을 위해 https도 추가해주었다.

나는 다 생성한 후에 뒤에 포스팅을 진행해서 선택이 불가능했다.

 

 

생성 후, 해당 로드밸런서의 리스너 및 규칙에서, HTTP 프로토콜의 규칙을 편집한다.

아래처럼, HTTP 요청이 왔을 경우 HTTPS로 리다이렉션 처리 해주었다.

로드밸런서가 HTTP 요청이 왔을 경우 HTTPS로 리다이렉트 요청을 시켜준다고 한다.

 

 

 

여기까지 완료하였다면, 본인의 도메인으로 접속할 때, http로 요청을 보내도 https로 리다이렉트 시켜준다.

 

아래의 사진은 요청보냈을 때, 응답이 https로 이루어진 모습이다. 짤로 만들지 못해 사진으로 첨부하고 마무리한다.

 

 

 

 

 

 

 

참조

https://velog.io/@tyjk8997/%EB%B0%B0%ED%8F%AC-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%97%90-HTTPS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-with-Route53-ALB

 

[배포] EC2 인스턴스에 HTTPS 적용하기 (with Route53, ALB)

HTTP는 Hyper Transfer Protocol의 줄임말입니다. 간단하게 표현하자면 서버와 클라이언트가 통신하는데 정해놓은 규약이라고 생각하면 편할 것 같습니다.HTTP 통신은 특별한 보안이 존재하지 않습니다.

velog.io

https://velog.io/@jupiter-j/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%A7%84%ED%96%89-route53-%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%97%B0%EA%B2%B0

 

[프로젝트 진행] route53 도메인 연결

WebRTC자체가 HTTPS환경이 적용되어야 카메라 등 통신을 원활하게 할 수 있기 때문에 프로젝트 테스트 전에 발급함

velog.io

 

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

GitHub Actions을 사용하기 위한 Token 발급 방법

삽질/사이드 프로젝트 2023. 9. 14. 14:41
728x90
728x90

 

 

현재 프로젝트 환경이 docker - gitactions을 통한 CI/CD구축이 되어 있어 너무 생소했다.

 

실습 겸 새로 프로젝트를 하나 생성하여 CI/CD를 구축해 볼 계획이다

 

그러기에 앞서 Token을 발급해보자

 

 

 

발급 방법

1. Settings - Developer Settings

Settings에 들어가서 최하단에 Developer Settings에 들어간다.

 

 

2. Personal access tokens 에서 Generate new token

토큰 발급을 해준다. workflow, write, delete권한은 주어야 한다.

 

 

 

[Feedback tracking] Fine-grained personal access tokens · community · Discussion #36441

This topic serves as an area for feedback and discussion on the new fine-grained personal access tokens format, launched on October 18th. It includes more permissions, mandatory expirations, and or...

github.com

만약 fine-grained tokens을 사용할 경우 토큰 만료기간을 무제한으로 설정할 수 없다. 1년이 최대인 것 같다.

 

또한 위 링크의 discussion처럼 여러 기능들이 제약되어 있다.

(GraphQL API를 사용할 수 없는 등 일부 기능이 정상적으로 동작하지 않는다)

 

입맛에 맞게 클래식이나 Fine-grained tokens 중 발급 받자.

 

 

이제 원하는 repo에서 Git Actions를 사용해볼 수 있

 

 

 

 

 

참조

https://velog.io/@siontama/Github-Fine-grained-tokens-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD

 

GitHub Fine-grained tokens 사용시 주의사항

GitHub가 정책상 비밀번호가 아닌 Personal Access Token(이 후 PAT)을 이용해서만 외부에서 Authorization을 할 수 있게 된 후 많은 분들이 PAT을 사용하고 있을 것이다.작년 10월 기존의 PAT을 Tokens (classic) 이

velog.io

 

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

[SpringBoot] 대량의 데이터를 어떻게 다루어야 할까

삽질/사이드 프로젝트 2023. 8. 12. 07:26
728x90
728x90

서론

★혹시 좋은 의견이 있으시다면 댓글로 좀 알려주시면 감사하겠습니다.. 초보 개발자에게 한줄기 빛을..

 

 

 

토이 프로젝트의 방향이 결국 리그오브레전드 챔피언들의 모의 투자 로 방향성이 잡혔다.

 

https://developer.riotgames.com/docs/lol

 

Riot Developer Portal

League of Legends Developer API Policy Before you begin, read through the Terms of Use and Legal Notices. Developers must adhere to policy changes as they arise. When developing using the API, you must abide by the following: Products cannot violate any la

developer.riotgames.com

위의 라이엇 공식 docs에서 챔피언 및 관련 정보를 확인할 수 있고 원하는 데이터를 사용할 수 있음

 

현재 포스팅하는 2023년 08월 11일 기준 챔피언 개수는 총 164개이며, 분 단위의 차트를 생성한다고 가정했을 때

분 단위로 기록해야하는 챔피언의 가격정보는 총 9,840개(164 * 60)이며

이를 일 단위로 환산했을 때 236,160건의 데이터가, 월 단위로는 700만 건의 데이터가 생성되게 되는데

 

처음 겪는 일이기 때문에 이를 어떻게 다루어 프로젝트에 적용시켜야 하는지 방향성을 잡기 위한 포스팅이 되겠다.

생각의 변화나, 좋은 방향으로의 학습 혹은 진행 상황이 개선된다면 포스팅을 주기적으로 업데이트 하도록 하겠다.

 

 

본론

현재 챔피언과, 챔피언 로그에 대한 테이블은 아래와 같다.

 

현재 테이블 구성이며, ChampionPriceLog에서 가격 변동에 대한 데이터를 관리하고자 했다.

 

(23.08.11)

하지만 대량의 데이터를 적재적소 핸들링하며 개발을 해 본 경험이 전무하기 때문에 세 가지 방향을 생각하고 있다.

 

1. 현 상황 유지

2. 가격 정보에 대한 DB를 새로 생성한 뒤, 일 단위의 테이블을 매번 생성 후 관리 (PriceLog230811)

3. 로그를 파일로 관리하고, 내 프로젝트에서 가장 중요한 매 09:00의 가격 정보만 PriceLog에 담는다.

 

1번의 장점은 한 테이블에서 모든 조회가 가능하다보니 조건에 원하는 조회 시간대만 잘 입력하면 되겠지만, 위에서 언급했듯이 2달만 지나도 1400만건의 데이터가 들어있을 것이고, 1년이면 7천만건...

인덱스를 적절하게 생성했지만, row가 늘어남에 따라 해당 테이블이 어떻게 될 지 잘 모르겠다. 아직 학습해야하는 부분인 것 같다.

 

2번의 경우 파티셔닝이라고 생각해도 무방할 것 같았다. 2번의 문제는, 과연 일 단위로 테이블을 생성하는 것에서 부터 시작됐다. 테이블 생성을 서버단의 코드에서 작성을 해야할지, 사용하는 DB의 이벤트 스케줄러를 통해 생성해주어야 하는지에서부터 두 가지의 정확한 장단점을 파악하지 못했다.

 

3번의 경우, 속도 측면에서 괜찮을 것 같다고 생각했지만 치명적인 단점이 있다. 로그 파일이 날아가면 차트를 구현할 수 가 없다. 다른 장단점들도 분명 존재하겠지만, 치명적인 단점이 있어 생각을 멈췄다.

 

논외로 모든 경우에서, 서버가 죽어버린다면? 과연 어떻게 구현해야 가장 관리가 용이하고 유지보수 또한 쉬울까에 대한 고민을 계속 하고있는 중이다.

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

[IntelliJ] IntelliJ와 Github 연동

삽질/사이드 프로젝트 2023. 6. 25. 18:55
728x90
728x90

IntelliJ Git 설정

Git 경로 설정

File - Settings - Git에서 깃 경로 설정

보통은 설치하면 자동으로 경로가 잡히는데, 깔려있지 않다면 Git을 설치하고 재시도 해보자.

 

 

GitHub 계정 연동

Add account 클릭 - Log in via GitHub 클릭

 

 

 

클릭하면 GitHub 로그인 - JetBrains에 권한 부여 후 연동이 완료됨


 

 

 

프로젝트 Git 연동

1. VCS - Enable Version Control Intergration 클릭 후 아래 화면처럼 나오면 OK 버튼 클릭

 

 

2. Git - Manage Remotes - Repository 주소 입력

 

 

3. Project 우클릭 - Git - Pull 진행

진행 시 빨간 색으로 없는 branch라고 나타날 시, Ctrl + F5를 눌려 Fetching 진행

만약 refusing to merge unrelated histories 에러가 발생하여 pull이 안된다면 아래의 명령어를 터미널에 입력.

git pull --allow-unrelated-histories REMOTE BRANCH

git pull --allow-unrelated-histories origin main

 

 

 

 

 

4. README.md 파일이 프로젝트에 추가된 것 확인 후 commit 탭에서 commit, push 진행

 

 

5. GitHub Repository 확인

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

검수 및 보수) 회원가입 - Spring Project(OTT Service)

삽질/사이드 프로젝트 2023. 3. 11. 18:27
728x90
728x90
이전 글 목록

1) 주어진 RFP를 바탕으로 주제 선정 - Spring Project(OTT 서비스)
2) ERD 설계 - Spring Project(OTT 서비스)
3) 회원 가입 기능 구현 - Spring Project (OTT 서비스)
4) 로그인, 로그아웃 기능 구현 - Spring Project (OTT 서비스)
5) 상세 페이지 및 회원 정보 수정 - Spring Project (OTT 서비스)
6) CRUD를 한번에 → 게시판 만들기(QNA게시판) - Spring Project(Mybatis) (OTT 서비스)
7) 게시판 페이징 처리 - Spring Project (OTT 서비스)
8) 카카오 지도 API 사용하기 - Spring Project (OTT 서비스)
9) (네아로) 네이버 로그인 API 활용 사이트 로그인 및 회원가입 - SPRING Project(OTT 서비스)
10) 카카오 로그인 API 사용하기(내 사이트 로그인 및 회원가입) - Spring Project(OTT Service)
11) 아임포트(포트원) API를 이용한 결제처리 - Spring Project(OTT Service)
12) 관리자 페이지 만들기(데이터 통계 및 chart.js, 유저 알고리즘) - Spring Project(OTT Service)
13) 관리자 페이지 (영상 정보 업로드 시 여러 테이블에 insert 및 update) - Spring Project(OTT Service)
14) 웹 소켓(Web Socket)을 활용한 실시간 알림 - Spring Service(OTT Service)
15) 웹소켓(WebSocket)을 활용한 관리자(1:N)와 사용자(1:1) 간의 채팅 만들기 - Spring Project(OTT Service)
16) 웹소켓(WebSocket)을 활용한 댓글 답글(대댓글)알림 - Spring Project(OTT Service)
17) 프로젝트 마무리 - Spring Project(OTT Service)

 

 

문제점


뷰에서 정규 표현식을 포함한 유효성 검사를 통해 가입 조건에 따라 가입을 한번 막고

회원가입 처리가 되기 전에 모델로 넘어올 때 당연히 조건을 통해 회원가입이 불가한 상황이라면 막아야 한다.

검수과정에서 원하는대로 되어있지 않았음을 발견했고, 수정 조치를 취했다.

 

 

수정


기존

@RequestMapping(value = "signup", method = RequestMethod.POST)
public ModelAndView createPost(UserDto userDto) {

    userDto.setPassword(encoder.encode(userDto.getPassword()));
    boolean tf = userService.create(userDto); //tf : 닉네임 중복여부 boolean
    ModelAndView mav = new ModelAndView();

    if (!tf) {
        mav.addObject("message", "fault");
        mav.setViewName("user/signup");
    }else {   //가입 성공
        mav.addObject("message", "success");
        mav.setViewName("common/start");
    }
    return mav;
}

기존 코드를 보니 tf를 선언하여 닉네임 중복여부만 파악한 후 가입을 진행시킨 모양이다.

모델에서의 검증이 없으니 당연히 모든 가입 절차가 끝난 후 아이디나 이메일, 휴대폰 번호를 지우고 가입하면 당연히 가입이 된다.

 

수정

@RequestMapping(value = "signup", method = RequestMethod.POST)
public ModelAndView createPost(UserDto userDto, ModelAndView mav) {
    if(userDto.getId() == null || userDto.getEmail() == null || userDto.getNickname() == null || userDto.getPhone_num() == null) {
        mav.addObject("message", "fault");
        mav.addObject("signUpFail", userDto);
        mav.setViewName("user/signup");
    }
    else {
        userDto.setPassword(encoder.encode(userDto.getPassword()));
        userService.create(userDto);
        mav.addObject("message", "success");
        mav.setViewName("common/start");
    }

    return mav;
}

길게 생각할 것 없이 생각나는대로 간단하게 수정했다.

1. 하나라도 null일 경우 가입이 안되도록 막았다.

2. 기존 설계자가 submit으로 전송하였기 때문에 페이지가 리로딩되는데, 유저의 편의성을 위해 userDto객체를 담아 view에 전송하였고, 실패의 경우 입력했던 값들이그대로 나올 수 있게 jstl 태그를 통해 설계했다.

<input value="<c:if test="${userDto.id != null}">${userDto.id}</c:if>

 

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

16) 웹소켓(WebSocket)을 활용한 댓글 답글(대댓글)알림 - Spring Project(OTT Service)

삽질/사이드 프로젝트 2023. 3. 6. 18:36
728x90
728x90
해당 프로젝트는 2023/01/25 ~ 2023/03/12 내에 진행되는
아카데미 내 수강생들끼리 팀을 나누어 진행한 모의 프로젝트입니다.
팀원은 6명이었으며, 프로젝트 리더를 맡았습니다.

 

이전 글 목록

1) 주어진 RFP를 바탕으로 주제 선정 - Spring Project(OTT 서비스)
2) ERD 설계 - Spring Project(OTT 서비스)
3) 회원 가입 기능 구현 - Spring Project (OTT 서비스)
4) 로그인, 로그아웃 기능 구현 - Spring Project (OTT 서비스)
5) 상세 페이지 및 회원 정보 수정 - Spring Project (OTT 서비스)
6) CRUD를 한번에 → 게시판 만들기(QNA게시판) - Spring Project(Mybatis) (OTT 서비스)
7) 게시판 페이징 처리 - Spring Project (OTT 서비스)
8) 카카오 지도 API 사용하기 - Spring Project (OTT 서비스)
9) (네아로) 네이버 로그인 API 활용 사이트 로그인 및 회원가입 - SPRING Project(OTT 서비스)
10) 카카오 로그인 API 사용하기(내 사이트 로그인 및 회원가입) - Spring Project(OTT Service)
11) 아임포트(포트원) API를 이용한 결제처리 - Spring Project(OTT Service)
12) 관리자 페이지 만들기(데이터 통계 및 chart.js, 유저 알고리즘) - Spring Project(OTT Service)
13) 관리자 페이지 (영상 정보 업로드 시 여러 테이블에 insert 및 update) - Spring Project(OTT Service)
14) 웹 소켓(Web Socket)을 활용한 실시간 알림 - Spring Service(OTT Service)
15) 웹소켓(WebSocket)을 활용한 관리자(1:N)와 사용자(1:1) 간의 채팅 만들기 - Spring Project(OTT Service)

 

 

우리 프로젝트에서 사용하는 웹소켓 마지막 장이다.

팀원의 대댓글 구현이 완료되어 대댓글 입력 시 댓글 작성자에게 알림을 보내는 기능을 마지막으로

어렵고도 재밌었던 소켓 다루기를 끝내보도록 하자.

 

 

대댓글 알림 만들기


우선 대댓글 입력 시에 대한 상황이기 때문에 대댓글이 작성될 때 정보를 보내는 쪽에서 같이 처리했다.

 

따로 스크립트에서 보낼 녀석이 없었다. 팀원이 설계해 놓은 코드를 보니

pid(원댓글 번호), 영상id를 다 가져오기 때문에 추가로 ajax에 담아 보낼 데이터가 없어서 바로 컨트롤러로 왔다.

Controller

//대댓글 작성하기 - 02.28 장민실
@RequestMapping(value="cocomwrite", method=RequestMethod.POST)
public ModelAndView cocomInsert(int pid, CommentDto dto, HttpSession session, ModelAndView mv) {
    String user_id = session.getAttribute("user_id").toString();
    String nickname = session.getAttribute("nickname").toString();
    int id = userService.getid(user_id);

    int depth = 1;          // depth=0 원댓글, depth=1 대댓글
    dto.setDepth(depth);
    dto.setPid(pid);

    dto.setUser_id(id);
    dto.setNickname(nickname);	

    commentService.cocomInsert(dto);

    /************************알람 - 03.06 장재호************************/
    alarmService.addComment(dto);
    /*****************************************************************/
    mv.addObject("cocom_dto", dto);
    return null;
}

 

/************************알람 - 03.06 장재호************************/
alarmService.addComment(dto);
/*****************************************************************/

 

Service / Impl / Dao

//Service
void addComment(CommentDto dto);

//ServiceImpl
@Override
public void addComment(CommentDto dto) {
    alarmDao.addComment(dto);		
}

//Dao
public void addComment(CommentDto dto) {
    ss.insert("alarm.addComment", dto);		
}

 

SQL.xml

<insert id="addComment">
    insert into ALARM (USER_ID, CODE, PREFIX)
    values ((select USER_ID from VIDEO_COMMENT where PID=#{pid} and DEPTH=0),
    "NewComment", (select TITLE from VIDEO where VIDEO_ID=#{video_id}))
</insert>

그저 insert만 하면 된다. QNA와 달리 로그인 했을 때 댓글 작성 권한이 있기 때문에 따로 로그인 여부의 체크는 필요없다.

댓글 작성자와, 해당 영상의 제목을 테이블에 넣었다. 이를 활용하여 알림을 주기위한 설계였다.

 

 

Handler.java

protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

	(...생략...)
    else if(code.equals("NewComment")) { //03.06 장재호 댓글추가
        code = "답글이 등록되었습니다.";
        prefix += " 영상";

    }
	(...생략...)
}

기존 알림을 보내는 Handler에서 조건이 ALARM 테이블에 code로 구분해서 JS에 전달하는 것이었기 때문에 조건만 따로 생성해주었다. 이게 끝이다.

소켓 알림에 대한 자세한 코드는 아래 링크에서 확인할 수 있다.

14) 웹 소켓(Web Socket)을 활용한 실시간 알림 - Spring Service(OTT Service)



 

확인


디자인은 진행중이니 양해부탁드립니다.

 

 

 

원 댓글에 답글이 작성이되면 아래처럼 ALARM 테이블에 NewComment로 저장되고

 

 

 

알람이 올바르게 등록되었다.

 

 

728x90
300x250
mag1c

mag1c

2년차 주니어 개발자.

방명록