노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

Firebase Messaging Notification



1. AndroidManifest.xml


2. Build the notification


# Cloud Messaging https://firebase.google.com/docs/cloud-messaging/android/client # Build Notification https://developer.android.com/training/notify-user/build-notification




블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Functions 샘플




// 에러 : TypeError: Cannot read property 'receiver_id' 


https://stackoverflow.com/questions/48031598/cloud-functions-for-firebase-fcm-reference-error




참고 : https://firebase.google.com/docs/functions/beta-v1-diff

Cloud 함수용 Firebase SDK 이전 가이드 : 베타에서 버젼 1.0으로 이전


> event매개 변수가 data 및 context로 분할됨



블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

Heroku Node.js security update



1. Heroku 연결하기 ( with Heroku CLI )



설치가 되어 있지 않거나 PC에서 삭제가 된 경우는 아래 CLI를 설치해야 한다.


https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up



설치가 완료되면, 윈도우 명령어 창에서 


$ heroku login 


을 실행하고, ID/PWD를 입력해서 로그인을 한다.




2. 윈도우로 APP 가져오기


$ heroku git:clone -a [APP-NAME]

$ cd [APP-NAME]


* [APP-NAME]은 Heroku 대시보드에서 해당 이름을 확인 필요




3. 윈도우에서 파일 수정하기 : package.json



참조 : Specifying a Node.js Version




4. Heroku로 Deploy하기


$ git status  ## option

$ git add .

$ git status  ## option

$ git commit -m "Upgrade Node.js version"

$ git push heroku master







블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Amazon, EC2(Ubuntu)에 java 설치하기



1. java version확인

$ java -version


2. os release 확인후 jdk

$ lsb_release -a


- Release : 16.04
$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk


- Release : 14.04

$ sudo apt-get update $ sudo apt-get install openjdk-7-jdk


2. apt-get 사용법


- Ubuntu 리눅스는 Debian GNU/Linux배포판을 기반으로 하는 운영체제


- Ubuntu는 패키지와 패키지의 정보를 저장하는 패키지 저장소라는 개념을 보유

# 저장소 정보 업데이트
$ sudo apt-get update

#저장소에 새로운 패키지를 설치
$ sudo apt-get install 패키지명

#설치된 패키지 업그레이드
$ sudo apt-get upgrade

#패키지 삭제
$ sudo apt-get remove 패키지명




참조


http://storyinglass.tistory.com/7 , CentOS(REDHAT계열) Java/Tomcat 설치

http://bahndal.egloos.com/588515,yum CentOS 패키지 관리자



CentOS에서 사용되는 패키지 관리자 yum

$ sudo yum update # 최신 버젼으로 CentOS 시스템의 sw를 업그레이드


$ sudo yum list all # 전체 패키지 목록 출력


$ sudo yum installed # 설치된 패키지 목록만 출력


$ sudo yum install [패키지명] # 패키지 설치

$ sudo yum remove [패키지명] # 패키지 제거


Install Java & Tomcat8 in CentOS


tomcat wget 및 실행
$ cd /opt
$ wget wget http://mirrors.advancedhosters.com/apache/tomcat/tomcat-8/v8.0.41/bin/apache-tomcat-8.0.41.tar.gz
$ tar xvf apache-tomcat-8.0.41.tar.gz
$ echo “export CATALINA_HOME=\”/opt/apache-tomcat-8.0.42\”” >> ~/.bashrc
source ~/.bashrc
$ cd /opt/apache-tomcat-8.0.42/bin
$ startup.sh

tomcat user 생성

$ sudo groupadd tomcat
$ sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat



Manager 앱 제거 - 해커의 침입 방지를 위해
$ cd /opt/apache-tomcat-8.0.42/webapps/
$ rm -rf manager/
$ rm -rf docs/
$ rm -rf examples/
$ rm -rf host-manager/

http://mobisoftinfotech.com/resources/mguide/set-apache-tomcat-based-jee-server-using-ubuntu-16-04-ec2-either-open-jdk-oracle-jdk/,How To Set Up Apache Tomcat Based JEE Server Using Ubuntu 16.04 On EC2 With Either Open JDK Or Oracle JDK


https://www.joinc.co.kr/w/Site/Linux/Documents/UbuntuPackageManagement,리눅스 패키지 관리 ( Ubuntu )


http://askubuntu.com/questions/843897/installing-java-on-ubuntu-amazon-aws, Installing java on Ubuntu Amazon aws [duplicate]


https://www.digitalocean.com/community/tutorials/how-to-install-apache-tomcat-8-on-ubuntu-16-04, How To Install Apache Tomcat 8 on Ubuntu 16.04


https://community.hortonworks.com/articles/77290/how-to-open-additional-ports-on-ec2-security-group.html, How to Open Additional Ports on EC2 Security Group ( 추가로 접근 port 열기 ) 





http://bigzero37.tistory.com/entry/Tomcat-7-%EC%97%90%EC%84%9C-ROOT-%EB%A1%9C-Deploy-%ED%95%98%EA%B8%B0, Tomcat 7 에서 ROOT 로 Deploy 하기


ROOT Context 고 뭐고 필요없이 그냥 war 파일명으로 Context를 올리려면 webapps 폴더 밑에 aaa.war 파일을 올려놓기만 하면 된다.


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.




Amazon/아마존, EC2 인스턴스에 XShell 접속하기




0. 인스턴스 생성 단계에서 키생성 하기


- 아래 메뉴에서 "Create Key Pair"를 선택하고, .perm파일을 로컬에 보관한다.






1. 인스턴스 생성 완료 후 Public DNS(IPv4)와 IPv4 Public IP를 확인



* Connect 버튼을 클릭하면, SSH에 관한 "ID"@"HOST"를 확인 할 수 있다.



2. XShell 설정


- HOST


- Method : Public Key, "ID"


- Import ( .perm )





참조 :


https://www.youtube.com/watch?v=Ogbbz5gCS3s, Connecting to the Amazon Cloud EC2 Server Using Netsarang XShell


http://storyinglass.tistory.com/5 , [AWS-EC2]생성한 EC2 인스턴스에 SSH로 접속하기


http://storyinglass.tistory.com/1, [AWS-EC2] AWS(아마존웹서비스) EC2 인스턴스 생성하기



인스턴스 OS 종류

- Amazon Linux , Red Hat Enterprise Linux , SUSE Linux Enterprise Server, Ubuntu Server, Microsoft Window Server 2012 R2





2단계: EC2 인스턴스 생성 및 웹 서버 설치


http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/CHAP_Tutorials.WebServerDB.CreateDBInstance.html,

1단계: RDS DB 인스턴스 만들기



https://community.hortonworks.com/articles/77290/how-to-open-additional-ports-on-ec2-security-group.html, How to Open Additional Ports on EC2 Security Group ( 추가로 접근 port 열기 ) 


'Cloud - Google,AWS' 카테고리의 다른 글

Heroku Node.js security update  (0) 2017.07.13
Amazon, EC2(Ubuntu)에 java 설치하기  (0) 2017.02.09
xftp로 구글 클라우드 연결하기  (2) 2016.06.27
블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

-- 미완성... 작성중...입니다.


실시간 댓글(발언/논평) 시스템 만들기




Why Should We Care About The Real-Time Web?

비록 실시간웹은 상대적으로 최근에 메인스트림 구절이지만, 실시간 웹 기술은 10여년이 넘게 되어 간다.


SOCIAL MEDIA DATA

소셜 미디어가,그리고 특히 트위터는, 갖는 의미는 더욱 더 데이타는 즉시 가용해져야 한다.


INCREASED USER EXPECTATIONS

더 많은 사용자가 트위터와 페이스북과 같은 어플을 사용하는 것으로 이동하게 되어, 그것들이 전달되는 사용자의 경험, 웹어플의 기대되어 지는 것들의 인지등이 변했다.


WEBSOCKETS

이전에 내가 언급했듯이 이전 솔루션은 서버에게 즉시 데이타를 웹브라우저로 푸시하는 것은 해킹으로 여겨졌다. 그러나 없어지지 않는 사실은 표준화되는 방법과 크로스 브라우저를 하는 능력이 요구되었다.

우리의 플레이어들은 마침내 HTML5 웹소켓을 가지고 해결을 해왔다.


HOW ARE REAL-TIME TECHNOLOGIES BEING USED?

실시간 웹 테크놀러지는 사용자 경험를 개선하는 것을 이끌고, 모든 종류의 매력적인 기능을 만드는 것을 가능하게 해 준다.


여기(아래는) 보통 사용되는 사용사례의 모음이다.

* Realtime Stats - 이 기술은 처음에 금융에서 주식 교환 정보를 보여주기 위해 쓰였고,

* Notifications - 어떤것을 사용자가 가용해지거나 변화에 관심을 가질때

* Activity Streams - 친구나 제품의 활동의 흐름

* Chat - 실시간 웹 기술 그러나 여전히 매우 값어치 있는 함수.

* Collaboration - 구글docs는 그들 문서안에서 이런 기능들의 종류를  제공한다.

* Multiplayer Games - 사용자의 움직임을 실시간으로 전달하는 능력, 게임 상태의 변화 그리고 점수의 갱신은 멀티플레이어 게임에서 매우 명확하게 중요하다.



Creating Generic Blog Commenting System


START FROM A TEMPLATE

나는 블로그 post에 실시간 댓글을 추가하는 것을 집중하려 하고, template으로 부터 시작을 하자.

이 template은 Coding An HTML 5 Layout From Scratch의 포스트에서 정의된 HTML 5 layout을 재사용한다.

 

 


/css(dir)

global-forms.css

main.css

reset.css

/images(dir)

/index.php


GitHub(https://github.com/pusher-community/realtime-commenting/tree/start)


HTML

주요소는

-<section id="content"> : 블로그 post content

-<section id="comments"> : comments가 보여지는 위치. 이것이 이 작업으로 만들어 지는 주요 위치이다.


COMMENTS ( 댓글 쓰는 Form추가 )

<div id="respond">가 <section id="comments">로 둘러 쌓인 채 추가 된다.

Leave a Comment

<-- comment_post_ID value hard-coded as 1 -->

COMMENT FORM CSS ( 댓글 쓰기 css 설정 )

#respond, #respond input, #respond textarea를 설정

#respond {
  margin-top: 40px;
}

#respond input[type='text'],
#respond input[type='email'], 
#respond textarea {
  margin-bottom: 10px;
  display: block;
  width: 100%;

  border: 1px solid rgba(0, 0, 0, 0.1);
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  -o-border-radius: 5px;
  -ms-border-radius: 5px;
  -khtml-border-radius: 5px;
  border-radius: 5px;

  line-height: 1.4em;
}


HANDLING COMMENT SUBMISSION ( POST 수신 부분 작성 )

form에서 전송하는 것을 받아들이고 저장하는 post_comment.php를 작성


add_comment($_POST) ) {
  header( 'Location: index.php' );
}
else {
  header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
?>


여기서는 실시간 기능에 관해서만 다루니 Persistence.php로 정의된 Template class를 사용

접속자의 $_SESSION을 사용해서 저장하는 방식으로 필요하다면 재수정을 해서 사용


DISPLAYING THE COMMENTS WITH THE BLOG POST

마지막으로 일반적인 블로그 코멘트 시스템을 설정해야 하는 것은 블로그 페이지를 갱신하는것이고, Persistence 객체로 부터 코멘트를 가져와서 보여주는 것이다.

$comment_post_ID는 1로 임의설정

아래 부분은 index.php상단에 위치(Redirect/Loading시에 가져옴)

get_comments($comment_post_ID);
$has_comments = (count($comments) > 0);
?>


POST시에도 해당 값으로 전달



모든 댓글을 보여주는 영역도 index.php에 설정

  1. Be the first to add a comment.
  2. By


Prograssive Enhancement With jQuery

블로그 댓글 시스템을 웹페이지 처럼 느끼지 않고, 어플처럼 느끼도록하는 과정의 첫 단계는

사용자가 댓글을 등록하면, 페이지가 reload되는 것을 중지 시키는 것이다.

이것은 댓글을 서버로 전송(등록)시 AJAX 요청을 사용할 수 있다.

여기서 사용할  jQuery는 크로스브라우저 자바스크립터 기능으로 표준이다.

만들 자바스립터를 위해 새로운 폴더를 만들고, 거기에 어플리케이션 스크립터를 위한 파일을 위치 시킨다.




CAPTURE THE COMMENT FORM SUBMISSION

form의 submit 이벤트를 웹페이지는 bind준비한다.

$(function() {
  $('#commentform').submit(handleSubmit);
});

form이 전송되게되면, handleSumbit함수는 form에서 추출한 서버로 보내길 원하는 댓글data를 모은다.

function handleSubmit() {
  var form = $(this);
  var data = {
    "comment_author": form.find('#comment_author').val(),
    "email": form.find('#email').val(),
    "comment": form.find('#comment').val(),
    "comment_post_ID": form.find('#comment_post_ID').val()
  };

  postComment(data);

  return false;
}

function postComment(data) {
  // send the data to the server
}


POST THE COMMENT WITH AJAX

postComment함수안에서 서버로 POST요청하여 form으로 부터 조회한 data를 전달한다.

또한 2개의 처리자:postSucces와 postError를 정의할 수 있다

function postComment(data) {
  $.ajax({
    type: 'POST',
    url: 'post_comment.php',
    data: data,
    headers: {
      'X-Requested-With': 'XMLHttpRequest'
    },
    success: postSuccess,
    error: postError
  });
}

function postSuccess(data, textStatus, jqXHR) {
  // add comment to UI
}

function postError(jqXHR, textStatus, errorThrown) {
  // display error
}


DYNAMICALLY UPDATING THE USER INTERFACE WITH THE COMMENT

서버에 댓글이 전달되고 저장되는 시점이지만 AJAX response는 어떤 의미 있는 응답을 제공하지 않는다.

또한, 사용자가 페이지를 갱신해서 보려고 해도, 댓글 영역은 새로 등록된 댓글을 보여주기 위해 갱신되지 않는다

이제, UI를 갱신하고 기능적으로 테스트하는 code를 작성한다.

function postSuccess(data, textStatus, jqXHR) {
  $('#commentform').get(0).reset();
  displayComment(data);
}
  
function displayComment(data) {
  var commentHtml = createComment(data);
  var commentEl = $(commentHtml);
  commentEl.hide();
  var postsList = $('#posts-list');
  postsList.addClass('has-comments');
  postsList.prepend(commentEl);
  commentEl.slideDown();
}

function createComment(data) {
  var html = '' +
  '
  • ' + '' + '
    ' + '

    ' + data.comment + '

    ' + '
    ' + '
  • '; return html; } function parseDisplayDate(date) { date = (date instanceof Date? date : new Date( Date.parse(date) ) ); var display = date.getDate() + ' ' + ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][date.getMonth()] + ' ' + date.getFullYear(); return display; }


    DETECT AND RESPONDING TO THE AJAX REQUEST

    post_comment.php갱신하여 AJAX call을 감지하고, 새로 생성된 댓글에 관한 정보를 return한다.

    // if (  isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {} 
    $ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');
    


    add_comment($_POST);
    
    if($ajax) {
      sendAjaxResponse($added);
    }
    else {
      sendStandardResponse($added); 
    }
    
    function sendAjaxResponse($added) {
      header("Content-Type: application/x-javascript");
      if($added) {
        header( 'Status: 201' );
        echo( json_encode($added) );
      }
      else {
        header( 'Status: 400' );
      }
    }
    
    function sendStandardResponse($added) {
      if($added) {
        header( 'Location: index.php' );
      }
      else {
        header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
      }
    }
    ?>
    


    Getting Real-Time - Finally !

    여기까지, ..위에서 작업한 것들이 가치가 있는 것이다. Pusher를 추가하는 것은 아주 쉽다.

    WHAT IS PUSHER?

    Pusher는 호스팅되는 서비스로 빠르고 쉽게 실시간 기능을 웹이나 모바일 앱에 추가하도록 해 준다.

    이것은 RESTful API를 제공해서 쉽게 어떤 앱에서 오는 이벤트도 쉽게 publish한다.

    이는 HTTP request와 WebSocket API이 실시간 양방향 통신을 위해 사용된다.

    SIGN UP FOR PUSHER AND GET YOUR API CREDENTIALS

    가입하고 API인증 값을 얻기, pusher_config.php에

    
    

    index.php에서 require를 추가를 한다. JavaScript에서 APP_KEY를 사용할 수 있도록 만들고,Pusher로 연결시에 사용

    
    
    
    

    REAL-TIME JAVASCRIPT

    첫번째 할일은 Pusher를 앱에 추가할때 Pusher 자바스크립트library를 포함시키고 Pusher로 연결한다.

    
    
    
    

    app.js에 Pusher기능을 추가한다.

    var pusher = new Pusher(APP_KEY);
    var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val());
    channel.bind('new_comment', displayComment);
    


    SENDING REAL-TIME EVENTS USING THE EVENT CREATOR

    Event Creator를 사용해서 서버측code를 작성하지 않고 기능을 테스트할 수 있다.

    위의 코드에서 event명은 'new_comment'이고 'comments-1'채널이다

    REAL-TIME PHP

    -index.php
    -css (dir)
    -images (dir)
    -post_comment.php
    -pusher_config.php
    -Persistence.php
    -squeeks-Pusher-PHP (dir)
    --lib (dir)
    ---Pusher.php
    

    이벤트는 아래 몇줄로 작동이 가능해진다.

    trigger('comments-1', 'new_comment', array(
      "comment_post_ID" => 1,
      "date" => "Tue, 21 Feb 2012 18:33:03 +0000",
      "comment" => "The realtime Web rocks!",
      "comment_author" => "Phil Leggetter"
    ));
    ?>
    

    몇가지 logic를 추가해야한다. trigger이벤트 전에

    - comment가 추가된것을 확인하고

    - $added 배열에서 unique댓글 구분자를 추출하고

    - 채널명을 구문하는 문자를 만든다

    - new_comment이벤트를 채널명에 $added 데이타를 보내도록 한다.

    post_comment.php

    add_comment($_POST);
    
    if($added) {
      $channel_name = 'comments-' . $added['comment_post_ID'];
      $event_name = 'new_comment';
    
      $pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
      $pusher->trigger($channel_name, $event_name, $added);
    }
    
    if($ajax) {
      sendAjaxResponse($added);
    }
    else {
      sendStandardResponse($added); 
    }
    
    function sendAjaxResponse($added) {
      header("Content-Type: application/json");
      if($added) {
        header( 'Status: 201' );
        echo( json_encode($added) );
      }
      else {
        header( 'Status: 400' );
      }
    }
    
    function sendStandardResponse($added) {
      if($added) {
        header( 'Location: index.php' );
      }
      else {
        header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
      }
    }
    ?>
    

    2개의 다른 browser 창에서 앱을 실행하면,하나의 창에서 댓글을 추가하자마자, 2번째 창에서 댓글이 (매직처럼)바로 나타나다.

    이제 실시간 댓글 시스템을 갖는거다.


    demo running : http://realtime-commenting.herokuapp.com/

    ( 소스 : https://github.com/pusher-community/realtime-commenting )


    Good Real-Time App Development Practices


    USE BROWSER DEVELOPER TOOLS


    CHECK CONNECTIVITY



    Conclusion



    원문 : How To Build A Real-Time Commenting System

    https://www.smashingmagazine.com/2012/05/building-real-time-commenting-system/





    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

    Pusher, 5분안에 실시간 chat widget를 만들기

    ( 원문 : https://pusher.com/tutorials/realtime_chat_widget )


    * 아래 내용을 실행하기 위해서는 Pusher.com에 가입이 필요함


    * 아래 부분에서 서버측은 PHP(xampp)를 사용하는 것으로 기술함


    다루는 내용은

    - PusherChatWidget 자바스크립트 library와 CSS를 HTML view에 추가하기

    - 갖고 있는 서버로 백엔드 예제 코드를 통합하기


    사용될 Demo 소스

    https://github.com/pusher-community/pusher-realtime-chat-widget

    - php는 root아래의 특정 폴더에 unzip한다. ( /pusher-realtime-chat-widget/src/... )


    - 클라이언트에 포함된것

    : jquery.min.js , pusher.min.js , PusherChatWidget.js , pusher-chat.css

    : 'src/index.html'에서 'src/chat.html'이 호출됨

    : 'src/chat.html'에서 new Pusher('YOUR_APP_KEY')는 실제 APP_KEY로 변경해야 함


     ( 원문 예제에 있는 

    chatEndPoint, channelName은 PusherChatWidget에 설정을 추가하지 말것,

    이미 function내부에서 default값을 갖고 있으며, 이 부분은 서버와 같게 되어 있음  )


    - 서버에 필요한것

    : 'src/php'안에서 composer install를 실행한다.

      ( vendor폴더가 생성되면서,아래에 pusher 서버 모듈이 설치됨 )

    : 'src/php'안의 config_example.php -> config.php로 복사하고, 내부 내용을 수정

      (APP_KEY, APP_SECRET, APP_ID를 pusher사이트에서 확인)

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


    6개의 추천할 만한 SDK : 모바일 앱에 그룹Chat을 추가


    비교 - 월 기본료/제한 연결수/제한장치수/제한저장공간/제한전송량/제한메시지수



    1.Mobile SDKs


    1) Scringo

    한 줄의 코드 만으로 설치가 가능한 모바일 SDK이다. 이 SDK를 추가하는 것은 모바일 앱을 전체화면 쳇 화면이나 수신함, 화면에서 swipe가 가능해진다. p2p쳇, 그룹쳇방등이 생긴다.

    앱을 좀 더 소셜화가 되도록 하는 것이 집중되어 있고, iOS, Andorid, Unity등 지원한다.


    2) Quickblox

    Scringo와 같은 기능들을 갖고 있지만, 설치가 모듈로 이루어 지며, 플랫폼을 몇가지 더 지원한다. 지원하는 플랫폼은 iOS, Android, Windows Phone 7, Blackberry, 그리고 Web이다.

    또한 REST API가 가능하도록 준비되어 있다.




    2. Backend & Messaging Services For Developers


    3) Talkray

    YCombinator가 지원하는 회사로 개발자 API를 지원하여, 그룹쳇과 p2p쳇, 뿐만 아니라 음성전화도 앱에 추가할 수 있다.


    4) Firebase

    YCombinator가 지원하며, 인기있는 쳇tool 웹사이트인 Envolve(웹사이트에 쳇room를 추가하록 지원)을 운영하는 팀이다. iOS/OSX, Java/Android,Node.js, HTML과 REST API로 접근할 수 있다. 또한 많은 예제를 제공하고, 초보지만 시작하는 것이 매우 쉽다.


    5) Pusher

    호스팅 되는 API로 실시간 메시징을 모바일이나 웹App에 추가할 수 있다. 당신에게 의미하는것은 당신은 메시징 백엔드를 구성하고 운영하는 것이 바로 가능하다. 이것은 쳇을 위해 매우 유용하지만, firebase처럼, 동시에 다른 많은 것들을 할 수도 있다.


    6) Pubnub

    이것은 클라우드 서비스이며, pusher외 비슷하고, 실시간 메시징을 모바일이나 웹app에 추가할 수 있다. 큰 차이점은 Pubnub는 매우 많은 SDK를 만들어 놓았다.



    이것은 iOS를 위한 메시징 SDK이고, 아이폰 메시징 앱 또는 왓츠앱과 유사한 메시징 UI를 갖고 있다.



    http://blog.hipmob.com/post/65053125695/6-best-sdks-for-adding-group-chat-to-your-mobile

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.



    PubNub Design Patterns


    -부제 : Real Time Platform에서 디자인 패턴




    Inbound Channel Pattern



    PubNub는 채널마다 모든 메시지를 저장하고 저장 공간과 재생 기능을 갖는다.

    히스토리 정보의 요청을 하는 것은 연결 단절로 놓친 부분의 메시지를 조회하기 위함이다.


    이런 공통 패턴을 사용하면, 수백의 채널을 갖고 있다면 어떻게 되는가?


    모든 각 채널의 히스토리를 호출하는 것은 덜 효율적이다. 채널 사용 하는 방법이

    히스토리 호출의 회수를 줄여주도록 어떻게 변경을 해야 하나?



    1) 1-1 Chat


    (1) Channel Per Chat


    내(a)가  4명의 사람과 개인대화를 한다면, 4개의 채널을 갖고, publish/subscribe를 한다.


    - 몇시간정도 연결이 끊긴후에 재시작하면, 4개의 히스토리를 요청한다.

    - 몇개월이 지난다면, 축적이 되어서 40명 정도의 친구가 있다면, 40개의 히스토리를 요청해야 한다.

    - 이렇게 누적이 되기 시작하면 비효율적으로 변경 된다.

    아주 많은 히스토리 api호출을 하는 것은 필요하지 않으며, 어떻게 하면 이것을 바꿀까?

    이것을 재검토 - 가능한 만큼 적게 히스토리 호출을 감소시키는 것으로 원한다.


    히스토리 호출을 하는것으로 내게 보내진 어떤 메시지던지 그 시점에 갖고 오도록 시도하는것이 무엇인가? 이는 내가 보낸 메시지를 항상 갖고 있기 떄문이다.


    일대일 chat을 다른 누군 인지를 함께 구분하는 것이 무엇일까?

    자료 자체만으로는 여기까지, 다른 이들과 한개의 chat채널은 구조상에 다른 차이점은  없다.



    (2) Chat Inbound Channels


    채팅 메시지가 전달 되는 것을 재설계 하면,


    각 유저는 inbound channel를 갖고, 어떤 유저나 채팅의 메시지를 보내기 위해 사용한다.


    - User B나 User C는 User A의 inbound channel로 메시지를 보낸다.

    - 반대로, User A가 답장을 할때, 각 User에게 대응되는 inbound channel로 답신한다.




    이 뜻은 User A의 놓친 모든 메시지를 갖고 오기 위해서는, 오직 inbound 채널에 히스토리 요청만이 필요하다. 이것은 email주소와 inbox를 갖는 것과 매우 유사하다.


    -내가 많은 대화를 갖고 있지만, 모두 한 장소로 들어 온다.

    -내 UI는 그것들을 논리적으로 분리하고, 그것은 체계화 하기 위해 metadata(to/from/subject)를 이용하여 그것을 이해하고 대화를 분리하는 방법이다.




    보이는 것과 같이, User들(B,C,D,E)은 보내는 모든 메시지는 분리되는 일대일chat으로 User A의 inbound 채널로 보내진다.


    - 마치 4명이 나에게 이메일 주소로 이메일을 보내는것과 같다.

    - 시각적으로 그것들은 UI에서 분리가 될것이지만, data는 옮겨지고, 체계화되어지고,

    단일 채널(User A의 inbound 채널)을 통해 들어오는 모든것들이다.



    2) Group Chat


    그룹chat의 경우에는, User A가 그룹으로 메시지를 전송하면, User는 다중으로 전송이 가능하고, 그룹내의 각각의 User의 inbound채널로 전송한다.


    만약 그룹이 아주 큰(사용자가 많은)경우, 예를 들어 10명이 넘게 그룹chat이라면, 원래 시나리오와 같이 채널을 분리해서 특정한 chat으로 분리하기를 원한다.


    이런 경우에 나는 history call이 상당하게 줄였다.


    JSON Structure


    원래 시나리오에서, 각 쳇은 분리된 채널이지만, 메시지는 아래처럼 생긴것을 받는다.


    - From User A t o User B , sent to channel_1111

    {

      message_id:10001,

      author: "user_a",

      content: "What are you doing this weekend?", 

      timestamp:1425244035

    }


    수신 채널 시나리오에서, 구조는 약간 다르게 좀 더 metadata가 UI를 위해 추가된다.


    - From User A to User B, send to channel_user_b

    {

      message_id:10001,

      chat_id:"user_a_user_b",

      author: "user_a",

      content: "What are you doing this weekend?", 

      timestamp:1425244035

    }


    물론, 좀 더 정보를 추가할 수 있으며, UI정보는 시각적,정렬,검색,tag등을 체계적으로
    사용할 수 있다. 보낼수 있는 어떤것도 제한은 없다. chat_id key는 쳇에 포함되어 UI식별을 돕는다.


    마지막으로, 그룹쳇을 위한 수신 방법으로 어떻게 보이지는지, 간단한 예제를 정리한다.


    - From User A to Group Chat, sent to channel_user_b and channel_user_c

    {

      message_id:10001,

      chat_id:"group_chat_1234",

      author: "user_a",

      content: "What are you doing this weekend?", 

      timestamp:1425244035

    }


    3) Hybrid Pattern


    하나 작은 팁은 위의 패턴에 추가를 할 수 있고, 이로인새 PubNub의 흥미로운 사용을 가능하게 한다. 2가지 패턴을 조합할 수 있다. 이로 인해 좀 더 특정한 방법이고 쉽게 과거 기록을 볼 수 있다.


    먼저, 수신채널을 사용할 수 있고, 또한 유저들 각각의 관계 사이에 복합적인 단독 채널을 사용할 수 있다.


    메시지를 보내려고 할때, 2중 퍼블리싱 된다 : 각 사용자는 수신 채널로 퍼블리싱하고, 또한 둘 사이의 복합 채널로 퍼블리싱한다.

    복합채널을 구독할 필요는 없다, 물론 히스토리를 메시지를 받기 위해 복합 채널을 통해 호출하지 않아도 된다. 


    단지, 히스토리를 복합(채널)에서 호출할떄는 둘 사이의 메시지를 보기 원하거나

    특정 시점으로 돌아가고자 할때 히스토리를 호출하면 된다.




    이 (방식은) 좀 더 쉽게 둘사이의 메시지 히스토리를 얻는것을 가능하게 하고, 왜냐면 수신 채널은 모든 주고받는 쳇 메시지가 섞여 있기 떄문이다. 그것은 특정 시점으로 돌아가는 것이 어렵다.


    http://scalabl3.github.io/pubnub-design-patterns/2015/03/05/Inbound-Channel-Pattern.html






    Advanced Channel Groups


    - Friend Lists, Status Feed and Presence










    http://scalabl3.github.io/pubnub-design-patterns/2015/08/11/Advanced-Channel-Groups-Friend-Lists-Status-Feed-And-Presence.html

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


    Real-Time Web Technologies



    아래 링크이 페이지는 계속 작업 중이며, 새로운 기술이 추가되는 계획이다.




    분류


    1. Hosted Real Time Services, 호스팅 실시간 서비스


    1) Ably


    2) PubNub


    3) Pusher


    4) Realtime.co


    5) Streamdata.io



    2. Self Hosted Real Time Solutions, 자체 호스팅 실시간 솔루션



    1) apche-websocket


    2) Beacon Push


    3) PHP WebSocket


    4) SignalR


    5) socket.io




    3. Web Socket Client Libraries, 웹소켓 클라이언트 라이브러리



    1) JavaScript  - Flash Socket FallBack


    2) ActionScript


    3) .Net


    4) Silverlight


    5) Java




    https://www.leggetter.co.uk/real-time-web-technologies-guide/

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


    Firebase and backend logic ( 번역 )


    - Question 

    Parse에서 다른 서비스를 고려중이다. Firebase에 어떻게 백엔드 로직을 만들 수 있나?

    서버측(또는 트리거)에서 모든 값을 검증하는 것을 원한다.

    생각하는 방식은

    1) nodejs server를 만든다. 물론 express를 사용한다.

    2) (비지니스) 로직를 다루는 미들웨어를 만든다.

    3) App에서 Rest요청을 보낸다. 그것은 미들웨어를 작동시킨다.

    4) firebase의 nodejs sdk를 사용해서 http request의 파라미터에 따라 값을 변경한다

    5) app firebase handler에서 변경된 내용을 감지하도록 구현한다.

    * 1번에서 전송하면, node server에서 http req를 받아 firebase에 업뎃하고,

    2,5,1번에게 반영된다.


    다른 좀 더 쉬운(방법)게 있나요? parse에서 클라우드 코드를 사용했고, (비지니스)로직은 클라이언트 측보다 서버측에 있길 원한다.


    - Answer 1

    Firebase Application의 일반적인 (시스템)구성은 "Where does Firebase fit In your app?"이라는 블로그 포스트에 아주 잘 정의가 되어 있다.

    Pattern1 : 100% Firebase-powered apps

    많은 Firebase중심의 app은 오직 client code로만 구성이 된다.


    Pattern2 : Firebase-powered app with server code

    오직 client code만으로 불가능한 경우에 해당한다. ( 3rd party API등을 사용)


    Pattern3 : Existing app with Firebase-powered features

    큰 사이트등을 위한 일반적인 패턴이다.

    ( 기존에 있던 모든 기능을 갖는 app을 재작업하려는 계획이 없을때등 )


    원하는 (시스템)구성은 Pattern3에 가장 근접하다. client측 code는 Firebase나 node.js서버 양족으로 직접 통신을 한다.


    또한 높게 추천하는 것은 Pattern2를 고려 하라는 것이다. 클라이언트와 서버 사이의 모든 상호작용은 firebase를 통하는 것이다. 이 구성의 아주 좋은 예제는 Flashlight search integration이다.


    - monitor multiple Firebase paths and index data in real time

    - communicate with client completely via Firebase

    (client pushes search terms to search/request and read results from search/result )

    - clean up old, outdated requests


    클라이언트가 search query를 firebase database에 쓴다. 서버가 요청을 대기하고, 쿼리를

    수행하고 결과를 (firebase) database에 써 준다. 클라이언트는 결과를 기다린다.


    간단하기 서버에 사용되기 위한 (코드) 윤곽

    이 마지막 접근 방식은 Client가 Server와 절대로 직접 통신하지 않는다. 걱정해야 하는 모든 잠재적인 문제들을 제거한다. 이런 이유로 이런 방식을 종종  server대신에 "bots"으로 언급한다.


    - Answer 2

    이렇게 하는 것이

    - 모든 입력은 검증하는 ".validate rules" 를 사용하라. 이것을 위해 서버는 필요가 없다.

    - 만약 실행해야 하는 작업이 있다면, Firebase Queue를 사용하라


    만약 이와 같이 사용하지 않는 다면, 2가지 문제점이 생길거다.

    - 직접 포스트한것 만을 사용하려면, 서버에서 권한 객체를  취하는것이 약간 까다로워진다.

    -  만약에 단순하게  firebase app을 변화를 감지하고 반응하는 인스턴스로 사용하면(위의 Pattern 2), 아마도 확장성 문제를 갖게 될 것 이다.
    백엔드가 확장되서 2개의 인스턴스가 되면, firebase편집은 그것들의 trigger task가 될 것이다.  각 인스턴스는 변경되었다는 통보를 받게되고, 동일 task가 서로 실행되어,
    결과 객체에 추가/교체를 서로 하고, 요청 객체를 서로 삭제하려고 할 것 것이다.

    이런 문제점들을 피하기 위해 Firebase Queue를 사용해라.



    REF :

    http://stackoverflow.com/questions/35360421/firebase-and-backend-logic



    추가 링크

    Mobile App Backend Services

    https://cloud.google.com/solutions/mobile/mobile-app-backend-services


    -mobile app을 위해서 backend를 만들때 고려할 부분들

    Limit on-device data storage
    Synchronize data across multiple devices
    Handle the offline case gracefully
    Send notifications and messages
    Minimize battery drain


    - design patters , Cloud Platform을 사용하는 다양한 방법



    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


    Firebase용 Query


    Where절들이 없다? Join 문장이 없다? 문제는 없다!





    SQL경험을 토대로, NoSQL 자료구조과 Firebase의 동적,실시간 Query환경의 자유로움을 이해하는데 어느 정도의 시간이 걸릴 수 있다.




    * Select a user by ID ( WHERE id=x )


    - Firebase궈리에서, record들은 "경로"에 저장이 된다. 경로는 데이타 계층구조에서 단순하게 URL이다. 샘플 데이타에서, 유저정보는 /user에 저장 되었다. 그래서 id를 통해서 record를 조회한다면, 단순하게 URL에 추가를 한다. (~/user/123 )


    new Firebase('https://example-sql.firebaseio.com/user/123')

    http://jsfiddle.net/katowulf/vQEmt/2/




    * Find a user by email address ( WHERE email = x )


    - 그러나 사용자를 URL 경로에 속하지 않는 무언가로 찾아야 하는 것은 어떻게 하나?


    정렬된 데이타가 친숙하게 되는 것이다. Email주소가 일반적 조회 방법이 되기 떄문에,

    새 record를 추가할때마다 setPriority()를 호출 할 수있다. 그리고, 우리는 나중에 그들을 조회할때 사용할 수 있다.



    new Firebase('https://example-sql.firebaseio.com/messages')

    .startAt(startTime).endAt(endTime)

    http://jsfiddle.net/katowulf/vQEmt/2/


    - 대부분의 경우에 정말 멋지고 유용하지만, 우선순위를 사용할수 없는 경우에는 어떻게 하나? 또는 검색을 위해서 하나의 field 보다 많은 것이 필요하면? 그러면 그것은 어떤 index들을 적용할 시간이다.




    * Get messages posted yesterday ( WHERE timestamp BETWEEN x AND y )


    - 어떤 범위의 데이타를 조회하려고 하는 경우에는 어떻게 하나?  우선순위 없이 데이타를 정렬하는 것은 이와 같이 꽤 유용하다.


    http://jsfiddle.net/katowulf/EZUtP/



    * Paginate through widgets ( LIMIT 10 OFFSET 10 )


    - 무엇보다 먼저, 일부 주장을 만들어 보자. 만약 정적 data set에 관해 이야기 하지 않는 다면, 페이지 번호를 매기는 행위는 매우 애매모호 해진다.

     

    예를 들어, 내가 어떻게 기록이 삭제되거나 끊임없이 자주 추가되어 변화하는 데이터 세트의 페이지 번호를 정의합니까? 어떻게 offset를 정의 합니까? 마지막 page는? 만약 이 질문들의 답변이 다르다면, 페이지 매기기는 아마도 올바른 답변이 아닐것이다.


    작은 페이지 매기기, 정적 data set(1 MB 이하)은 클라이언트 side에서 전체 가능하다.

    큰 정적 data set의 경우는, 좀 더 도전을 받게 되는 상황이다.


    추가 저장만을 하는 data라고 가정하면, 위의 예제들 처럼 정렬된 data를 사용할 수 있고,

    각 메시지의 페이지 번호나 절대 증가 수치를 할당하고 startAt()/endAt()를 사용할 수 있다.


    new Firebase('https://example-sql.firebaseio.com/messages')

    .startAt(2)   // assumes the priority is the page number

    .endAt(2)


    그러나 예제(widget) 경로와 같이 작업을 하는 경우, 우선 순위를 갖고 있지 않다면?

    우선 순위를 위해 null를 전달하여 이전 페이지의 마지막 record를 단순하게 "start at"으로 할수 있다.


    new Firebase( 'https://example-sql.firebaseio.com/widget' )

    .startAt( null, lastWidgetOnPrevPage )  

    .limitToFirst( LIMIT + 1 )     // add one to limit to account for lastWidgetOnPrevPage


    http://jsfiddle.net/katowulf/qJNJW/



    * Join records using an is ( FROM table1 JOIN table2 USING id )


    - Firebaser(Firebase 개발자)가 비정규화(denormalization)에 대해 많은 이야기를 하고 있고,이는 좋은 충고이지만, 어떻게 한번 분리를 시킨후에 다시 합칠까요?


    자, 그게 보이는 것보다 매우 파격적으로 단순하다.


    Firebase는 실시간 sync 플랫폼이다. 속도와 효율성을 위해서 만들어 졌다.

    추가 참조를 만드는 것을 걱정할 필요가 없으며, 조회하고자 하는 데이타 만틈 많은 경로를 살필 수 있다.


    var fb = new Firebase( 'https://example-sql.firebaseio.com/' )

    fb.child('user/123') { 

    fb.child('media/123')

    }


    http://jsfiddle.net/katowulf/SSnfr/



    <원문 사이트>


    쿼리들, 파트1 : Firebase용으로 변환된 일반 SQL 쿼리들 , updated Nov 4, 2014

    https://firebase.googleblog.com/2013/10/queries-part-1-common-sql-queries.html

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

    (1) 소개 - Firebase

     

     

     

    Firebase서비스에서 생성한 Firebase프로젝트는

    해당 Firebase프로젝트를 통해 플랫폼 간에 사용자, 데이터 및 분석 자료를 공유하여 사용자의 기기와 관계없이 동일한 경험을 제공하고 모든 실적을 한 곳에서 관리할 수 있습니다.

    Firebase를 사용하는 모든 앱은 Firebase 프로젝트 하나에 연결됩니다. 프로젝트에서 Firebase 콘솔을 통해 앱의 모든 버전(Android, iOS, 웹)을 관리할 수 있습니다.

     

     

    서비스를 소개하는 YouTube 동영상의 설명 문구들


    성공적인 앱을 개발하기란 쉽지 않습니다.    
    Developing a successful app isn't easy.

     

    사용자를 고려한 다양한 버젼의 앱(Android, iOS, Web)의 개발을 고려해야 하고
    1) To reach a broad audience, you'll need to consider your iOS, Android, and mobile Web users.

     

    데이타를 저장하고 앱을 연동할 백엔드 서버를 구성해야 하며

     2) And to build for these platforms, you'll need a back-end server to store data and support the apps.

     

    사용자가 많이 접속하게 된다면 백엔드는 확장을 해야 한다
    3) Of course, you want to get your users logged in, hopefully lots of users, which means your back end wil have to scale.

     

     그리고, 확장에 때란 문제점들을 해결해야 하는 것이 따라온다

     And then after you've solved your scaling problems, 

     

    4) 또 새로운 사용자를 늘리는 방안도 찾아야 하며
    you have to find more ways to spread the world to get new users.

     

    5) 모든 활동을 측정하는 방안도 찾아야 한다.
    But have you found a way to measure all this activity?
         

     

    And, oh, no, your app is crashing and causing service to melt down,  and you haven't event made a dime yet.
     
    Don't you wish this could be easier?   This is why we build Firebase


     

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,
    노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


    xftp로 구글 클라우드 연결하기

     

     

    구글 클라우드플랫폼에서 제공하는 Compute Engine은 VM 인스턴스의 SSH 연결을 브라우저콘솔형태로 제공을 하고 있다.

     

     

    추가로 파일 업로드나 전용 SSH Terminal를 사용해야 할 때가 있으니, 등록해서 사용하는 것이 필요하다.

     

    좌측 메뉴의 메타데이터 -> SSH키를 통해서 SSH키를 추가할 수 있다.

     

    아래 링크를 따라가면, 자세한 설명을 볼 수 있다. 하지만 내용이 읽으려니 많다..(?)

    간단하게 설명하면 SSH key-pair를 만들어서 public키를 등록하면, private key를 사용하는 클라이언트가 구글 클라우드로 직접 접속이 가능하다.

     

    https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys?hl=ko&_ga=1.241264386.1201727008.1464839575 

     

    ssh-keygen : ssh-keygen -t rsa -f ~/.ssh/[KEY_FILE_NAME] -C [USERNAME]

     

     

    간단하게 Xftp를 통해서 그림으로 정리를 해 보면,

     

    1. 신규 세션을 생성하면서, Login방법은 "Public Key"로 선택하고, User Name를 입력하고,

    UserKey:부분의 Browse...선택한다.

    2. User Key 팝업 화면을 볼 수 있으며, 해당 화면에서는 Generate를 클릭한다.

     

    3. 다음의 옵션 선택은 Default 설정으로 넘어간다.

     

     

    4. 다음 화면도 Next를 선택한다.

     

     

    5. Key Name를 디폴트로 선택하고, 아래 Passphrase에 사용할 User key를 입력한다.

    ( 예)1234abc , abc1234)

     

    6. 아래와 같은 key 생성이 되며, Finish를 누르면 된다.

     

    7. 해당 Public Key를 구글 클라우드 메타데이터-SSH에 등록을 하면 된다.

     

    등록시에 

     

    키가 잘못되었습니다. 필수 형식: <protocol> <key-blob> <username@example.com> 또는 <protocol> <key-blob> google-ssh {"userName":"<username@example.com>","expireOn":"<date>"}  

     

    과 같은 오류 메시지를 보게 된다.

    이때 Public key 맨 마지막에

     

     

     

    해당 부분을 추가 하면 에러가 없어진다.

     

    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,