<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>heeestorys</title>
    <link>https://heeestorys.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 04:07:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>리딩리드</managingEditor>
    <item>
      <title>티스토리 블로그에 후원버튼(donaricano) 만드는법</title>
      <link>https://heeestorys.tistory.com/1040</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;안녕하세요. 요즘 유튜브와 BJ방송을 보면 많은 사람들이 크리에이터에게 후원을 합니다. 이젠 블로그에서도 후원을 받을 수 있습니다. 어떻게 받을 수 있는지 알아보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 도네리카노 사용하기&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://donaricano.com/&quot;&gt;https://donaricano.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1593441177722&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;유튜브, 블로그, BJ, 아티스트의 손쉬운 후원문화로 세상에 좋은 변화를 만듭니다. | 도네리카노&quot; data-og-description=&quot;유튜버, 블로거, BJ, 아티스트, 디자이너, 예술가에게 향긋한 커피 한잔을 선물하세요. 커피 한잔이 세상에 좋은 울림이 됩니다.&quot; data-og-host=&quot;donaricano.com&quot; data-og-source-url=&quot;https://donaricano.com/&quot; data-og-url=&quot;https://donaricano.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/10V0X/hyGAxo6pez/kt3opOX9gB2MTzFkRYYJkK/img.png?width=360&amp;amp;height=360&amp;amp;face=0_0_360_360&quot;&gt;&lt;a href=&quot;https://donaricano.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://donaricano.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/10V0X/hyGAxo6pez/kt3opOX9gB2MTzFkRYYJkK/img.png?width=360&amp;amp;height=360&amp;amp;face=0_0_360_360');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;유튜브, 블로그, BJ, 아티스트의 손쉬운 후원문화로 세상에 좋은 변화를 만듭니다. | 도네리카노&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;유튜버, 블로거, BJ, 아티스트, 디자이너, 예술가에게 향긋한 커피 한잔을 선물하세요. 커피 한잔이 세상에 좋은 울림이 됩니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;donaricano.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;- 도네리카노라는 서비스입니다. 도네리카노를 통해 네이버, 티스토리 블로그에서 후원버튼을 만들 수 있습니다. 또한 자신의 개인 카카오 QR코드를 업로드하기 때문에 수수료없이 무료로 후원 받을 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 도네리카노 회원가입 및 마이페이지 꾸미기&lt;/h3&gt;
&lt;p&gt;- 회원가입을 하게되면 마이페이지로 이동하게 됩니다. 마이페이지는 사용자들에게 노출되는 페이지입니다. &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;그렇기 때문에 대쉬보드를 클릭하여 개성있는 글과 함께 자신의 카카오 QR코드 이미지를 업로드하여 업데이트 합니다. 화면에 보이는 펜을 누루면 업데이트를 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;1324&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CLqXn/btqFcOgwiIY/xGkRex8mxtKwdr8iKLRJIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CLqXn/btqFcOgwiIY/xGkRex8mxtKwdr8iKLRJIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CLqXn/btqFcOgwiIY/xGkRex8mxtKwdr8iKLRJIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCLqXn%2FbtqFcOgwiIY%2FxGkRex8mxtKwdr8iKLRJIK%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;1324&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 마이페이지에서 확인하기&lt;/h3&gt;
&lt;p&gt;- 이제 자신의 마이페이지를 확인하면 알맞게 적용된것을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;271&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqmLtu/btqFdnQxbaY/hP8XmRXxrZ8xKrrAMfhbr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqmLtu/btqFdnQxbaY/hP8XmRXxrZ8xKrrAMfhbr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqmLtu/btqFdnQxbaY/hP8XmRXxrZ8xKrrAMfhbr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqmLtu%2FbtqFdnQxbaY%2FhP8XmRXxrZ8xKrrAMfhbr0%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;271&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;후원 하시는 분들이 도네리카노 버튼을 클릭하면 보이게되는 페이지 입니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 도네리카노 버튼 블로그에 적용하기&lt;/h3&gt;
&lt;p&gt;- 다시 대쉬보드로 돌아가면 하단에 주황버튼 두개가 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;432&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PvCBz/btqFft9nIX9/LyW0vH44fWVugkPGrSHFq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PvCBz/btqFft9nIX9/LyW0vH44fWVugkPGrSHFq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PvCBz/btqFft9nIX9/LyW0vH44fWVugkPGrSHFq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPvCBz%2FbtqFft9nIX9%2FLyW0vH44fWVugkPGrSHFq1%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;432&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;오른쪽 버튼을 클릭합니다. 그럼 아래와 같은 창이 뜨는걸 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;1264&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pIrBG/btqFcOt1agk/jhc2sGzX9RxQ1PqXDYqY0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pIrBG/btqFcOt1agk/jhc2sGzX9RxQ1PqXDYqY0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pIrBG/btqFcOt1agk/jhc2sGzX9RxQ1PqXDYqY0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpIrBG%2FbtqFcOt1agk%2Fjhc2sGzX9RxQ1PqXDYqY0k%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;1264&quot; width=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;알맞은 버튼에 크기를 선택하여 소스코드를 복사합니다. 자세한 사용방법은 사용방법 보기 버튼을 클릭하시면 나옵니다. 저는 티스토리에 추가하는것이 목표이기 때문에 티스토리에 적용하는 블로그 주소를 참고했습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.naver.com/tipup_manager/221987927495&quot;&gt;https://blog.naver.com/tipup_manager/221987927495&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1593441167277&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;티스토리에 도네리카노 적용하기&quot; data-og-description=&quot;안녕하세요. #도네리카노 입니다. 이번 글에서는 #티스토리에 도네리카노 버튼을 적용하는 방법을 알아보도...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://blog.naver.com/tipup_manager/221987927495&quot; data-og-url=&quot;https://blog.naver.com/tipup_manager/221987927495&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dGMWZt/hyGAEaHfvH/rgB3we5TkUh0xe5DQiu29K/img.png?width=743&amp;amp;height=393&amp;amp;face=0_0_743_393,https://scrap.kakaocdn.net/dn/VM6pf/hyGAvkyI35/aBKkmO1X8X4e26KmxfFZA1/img.png?width=400&amp;amp;height=668&amp;amp;face=0_0_400_668&quot;&gt;&lt;a href=&quot;https://blog.naver.com/tipup_manager/221987927495&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.naver.com/tipup_manager/221987927495&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dGMWZt/hyGAEaHfvH/rgB3we5TkUh0xe5DQiu29K/img.png?width=743&amp;amp;height=393&amp;amp;face=0_0_743_393,https://scrap.kakaocdn.net/dn/VM6pf/hyGAvkyI35/aBKkmO1X8X4e26KmxfFZA1/img.png?width=400&amp;amp;height=668&amp;amp;face=0_0_400_668');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;티스토리에 도네리카노 적용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;안녕하세요. #도네리카노 입니다. 이번 글에서는 #티스토리에 도네리카노 버튼을 적용하는 방법을 알아보도...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;저도 서식을 만들어 추가했습니다! 예전에 buy me a coffee 라는 서비스도 있었지만 외국버전이고 paypal을 사용해야되서 짜증났지만 도네리카노라는 서비스를 통해 블로거도 편하게 후원받을 수 있어서 좋은것 같습니다 ㅎ&lt;/p&gt;</description>
      <category>FullStack/혼자만드는웹서비스</category>
      <category>buymeacoffee</category>
      <category>도네리카노</category>
      <category>카카오QR코드</category>
      <category>카카오페이QR</category>
      <category>후원버튼</category>
      <category>후원서비스</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1040</guid>
      <comments>https://heeestorys.tistory.com/1040#entry1040comment</comments>
      <pubDate>Mon, 29 Jun 2020 23:36:15 +0900</pubDate>
    </item>
    <item>
      <title>[Testing Library] React-testing-libaray 란?</title>
      <link>https://heeestorys.tistory.com/1037</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;React-testing-library 란?&lt;/h3&gt;
&lt;p&gt;리엑트를 개발하다보면 TDD에 관해서 한번씩 생각하게 합니다. 화면에 소스가 렌더링 되기전에 커맨드라인으로 미리 확인 할 수 있다면 개발속도가 더 빠를까라는 생각을 하게 됩니다. 그러나 개발의 생산성을 올리기위해 TDD를 진행한다면 이 방법은 해답이 될 수도 있고 아닐 수도 있습니다.&lt;/p&gt;
&lt;p&gt;TDD는 오히려 빠른개발을 방해할 수도 있습니다. 하지만 더 견고한 어플리케이션을 제작할 수 있다는 사실은 반론할 수 없습니다. 더 견고하고 신뢰할 수 있는 웹 서비스를 만들기 위해서 react-testing-library를 사용합니다.&lt;/p&gt;
&lt;p&gt;react-testing-library는 결국 react 컴포넌트의 DOM테스트를 하기위한 TDD 도구로 사용됩니다. Testing-library란 패키지안에 react-testing-libary가 존재하며 설치방법 또한 npm 을 이용하여 간편하게 설치가 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1575262097002&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install --save-dev @testing-library/react&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;react 테스팅 도구로 과거에는 enzyme을 사용했지만 react 의 공식문서에서 react-testing-library 를 테스트 도구로 사용하는것을 권장하고 있습니다. 지금부터 react-testing-library의 사용법을 천천히 따라가 보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://testing-library.com/docs/react-testing-library/intro&quot;&gt;https://testing-library.com/docs/react-testing-library/intro&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1575262171505&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Testing Library &amp;middot; Simple and complete testing utilities that encourage good testing practices&quot; data-og-description=&quot;Simple and complete testing utilities that encourage good testing practices&quot; data-og-host=&quot;testing-library.com&quot; data-og-source-url=&quot;https://testing-library.com/docs/react-testing-library/intro&quot; data-og-url=&quot;https://testing-library.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bcK7hW/hyDXOesvo8/aS9z8k6IkcHKNedeKzvWYk/img.png?width=128&amp;amp;height=128&amp;amp;face=0_0_128_128,https://scrap.kakaocdn.net/dn/m20IY/hyDXOldHhI/4HGCbkaamzKt2Xk5AwnMsk/img.png?width=128&amp;amp;height=128&amp;amp;face=0_0_128_128,https://scrap.kakaocdn.net/dn/fEoJl/hyDV4JXXJ9/bRLNMM9yZYkHUrkdE5g1Ek/img.png?width=1280&amp;amp;height=247&amp;amp;face=0_0_1280_247&quot;&gt;&lt;a href=&quot;https://testing-library.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://testing-library.com/docs/react-testing-library/intro&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bcK7hW/hyDXOesvo8/aS9z8k6IkcHKNedeKzvWYk/img.png?width=128&amp;amp;height=128&amp;amp;face=0_0_128_128,https://scrap.kakaocdn.net/dn/m20IY/hyDXOldHhI/4HGCbkaamzKt2Xk5AwnMsk/img.png?width=128&amp;amp;height=128&amp;amp;face=0_0_128_128,https://scrap.kakaocdn.net/dn/fEoJl/hyDV4JXXJ9/bRLNMM9yZYkHUrkdE5g1Ek/img.png?width=1280&amp;amp;height=247&amp;amp;face=0_0_1280_247');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Testing Library &amp;middot; Simple and complete testing utilities that encourage good testing practices&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Simple and complete testing utilities that encourage good testing practices&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;testing-library.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Tools/react-testing-library</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1037</guid>
      <comments>https://heeestorys.tistory.com/1037#entry1037comment</comments>
      <pubDate>Mon, 2 Dec 2019 13:50:04 +0900</pubDate>
    </item>
    <item>
      <title>[ReactNative] 리엑트네이티브 설치하기</title>
      <link>https://heeestorys.tistory.com/1036</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;리엑트네이티브&lt;/h3&gt;
&lt;p&gt;리엑트 네이티브를 처음 설치하는 사람이라면 조금은 혼동이 될 수 있다. 유튜브나 블로그에 적힌 글을 보면 expo-cli 를 이용한 간단한 방법 소개가 많다.&amp;nbsp;&lt;br /&gt;그 이유는 그만큼 react-native 를 빠르게 접할 수 있으며 누구나 어느 환경에서든 개발을 할 수 있기때문이다. 하지만 간편함에는 한계가 있다고 생각합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;expo-cli와 react-native-cli 차이&lt;/h3&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;expo-cli&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 간편한시작이 가능합니다.&lt;br /&gt;- 배포가 편하고 업데이트는 expo에 publish 만 해주면 끝납니다&lt;/p&gt;
&lt;p&gt;- Expo 에서 제공하는 API 만 사용할 수 있습니다.&lt;br /&gt;- native&amp;nbsp; 파일을 제어할 수 없습니다.&lt;br /&gt;- 나중에 프로젝트가 커지면 Expo 파일을 ejet 해서 사용해야 합니다.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;react-native-cli&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- OS 환경에 따른 셋팅이 필요합니다.&lt;br /&gt;- 개발툴 또한 xcode, android studio를 필요로 합니다.&lt;br /&gt;- expo에서 불가능했던 native의 필요한 부분을 컨트롤 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;결국은 expo에서 시작했지만 프로젝트의 요구사항이 다양해진다면 어쩔 수 없이 react-native-cli로 넘어가게 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;리엑트네이티브 설치&lt;/h3&gt;
&lt;p&gt;설치는 react-native 페이지를 참고합니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://facebook.github.io/react-native/docs/getting-started&quot;&gt;https://facebook.github.io/react-native/docs/getting-started&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1575006817315&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;React Native &amp;middot; A framework for building native apps using React&quot; data-og-description=&quot;A framework for building native apps using React&quot; data-og-host=&quot;facebook.github.io&quot; data-og-source-url=&quot;https://facebook.github.io/react-native/docs/getting-started&quot; data-og-url=&quot;https://facebook.github.io/react-native/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/B1gqS/hyDTWR6ECI/IsNVsCIbxDu1IKJK0BqueK/img.png?width=600&amp;amp;height=780&amp;amp;face=0_0_600_780,https://scrap.kakaocdn.net/dn/Csq0w/hyDTRQMNns/E4KU3WK7i6laSQJ3yBQfK0/img.png?width=602&amp;amp;height=776&amp;amp;face=0_0_602_776,https://scrap.kakaocdn.net/dn/t9xVa/hyDT2Y4KlM/DwKBdNSG8bT2dTqBmO8xVK/img.png?width=602&amp;amp;height=776&amp;amp;face=0_0_602_776&quot;&gt;&lt;a href=&quot;https://facebook.github.io/react-native/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://facebook.github.io/react-native/docs/getting-started&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/B1gqS/hyDTWR6ECI/IsNVsCIbxDu1IKJK0BqueK/img.png?width=600&amp;amp;height=780&amp;amp;face=0_0_600_780,https://scrap.kakaocdn.net/dn/Csq0w/hyDTRQMNns/E4KU3WK7i6laSQJ3yBQfK0/img.png?width=602&amp;amp;height=776&amp;amp;face=0_0_602_776,https://scrap.kakaocdn.net/dn/t9xVa/hyDT2Y4KlM/DwKBdNSG8bT2dTqBmO8xVK/img.png?width=602&amp;amp;height=776&amp;amp;face=0_0_602_776');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;React Native &amp;middot; A framework for building native apps using React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;A framework for building native apps using React&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;facebook.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mW1Rw/btqz6ufsThz/RJWXwH4B6uLuwEs0XESWqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mW1Rw/btqz6ufsThz/RJWXwH4B6uLuwEs0XESWqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mW1Rw/btqz6ufsThz/RJWXwH4B6uLuwEs0XESWqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmW1Rw%2Fbtqz6ufsThz%2FRJWXwH4B6uLuwEs0XESWqk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위페이지에서 expo-cli 와 react-native-cli를 이용한 설치방법을 알 수 있습니다.&lt;br /&gt;react-native-cli를 선택하게 되면 OS 구분에 따른 설치방법이 나옵니다. 저는 로컬에 macOs를 이용한 방법으로 설치했습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V8fwk/btqz7pq1rMY/gINob3N96xirjcFoLsqngK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V8fwk/btqz7pq1rMY/gINob3N96xirjcFoLsqngK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V8fwk/btqz7pq1rMY/gINob3N96xirjcFoLsqngK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV8fwk%2Fbtqz7pq1rMY%2FgINob3N96xirjcFoLsqngK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;문서가 꽤나 잘 정리되어있습니다. 하지만 maxOs 환경에서 설치시에 먼저 xcode 업데이트를 체크해주시기 바랍니다.&amp;nbsp;&lt;br /&gt;저는 처음에 설치할때 xcode 버전문제로 조금 고생을 했습니다 ㅠㅠ&lt;/p&gt;</description>
      <category>Front-End/ReactNative</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1036</guid>
      <comments>https://heeestorys.tistory.com/1036#entry1036comment</comments>
      <pubDate>Thu, 28 Nov 2019 19:29:59 +0900</pubDate>
    </item>
    <item>
      <title>[ReactNative] 리엑트 네이티브란?</title>
      <link>https://heeestorys.tistory.com/1035</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 리엑트 네이티브란?&lt;/h3&gt;
&lt;p&gt;요즘 크로스플랫폼이라는 단어를 많이 사용하게됩니다. 크로스플랫폼 혹은 멀티플랫폼이라고도 하는 개발 도구들이 우후죽순 생겨나기 시작했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;크로스플랫폼도구란 하나의 언어로 다양한 플랫폼인 web, ios, android 등을 개발할 수 있는 도구를 말합니다. 예를 들어 angular의 ionic, 구글의 flutter, c#으로 개발하는 xamarin, 마지막으로 리엑트 네이티브까지 개발자들은 행복한 고민에 놓일 수 있습니다.&lt;/p&gt;
&lt;p&gt;이런 도구들 중 가장 핫하게 뜨고있는 리엑트 네이티브는 2017년 부터 지금까지 독주를 이어오고 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://cogi.kr/rn&quot;&gt;https://cogi.kr/rn&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1574918375905&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코기(cogi) - 알기쉬운 단축 URL&quot; data-og-description=&quot;&quot; data-og-host=&quot;cogi.kr&quot; data-og-source-url=&quot;https://cogi.kr/rn&quot; data-og-url=&quot;https://cogi.kr/rn&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cogi.kr/rn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cogi.kr/rn&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코기(cogi) - 알기쉬운 단축 URL&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;cogi.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://cogi.kr/rn2&quot;&gt;https://cogi.kr/rn2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1574918500117&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코기(cogi) - 알기쉬운 단축 URL&quot; data-og-description=&quot;&quot; data-og-host=&quot;cogi.kr&quot; data-og-source-url=&quot;https://cogi.kr/rn2&quot; data-og-url=&quot;https://cogi.kr/rn2&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cogi.kr/rn2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cogi.kr/rn2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코기(cogi) - 알기쉬운 단축 URL&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;cogi.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;위의 URL을 통해 흥미로운 비교를 해보시기 바랍니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;도구들 중에 저희가 집중하고있는 것은 리엑트 네이티브 입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점&lt;/h4&gt;
&lt;p&gt;- 어마어마한 생산성&lt;br /&gt;- UI 패키지&lt;br /&gt;- 라이브리로딩&lt;br /&gt;- 코드푸시&lt;br /&gt;- 자바스크립트 코드를 이용한 문법&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점&lt;/h4&gt;
&lt;p&gt;- 뷰 스택이 쌓일수록 느림&lt;br /&gt;- expo-cli 사용시 native 기술 한계&lt;br /&gt;- native-cli 사용시 os 영역이 존재&lt;/p&gt;
&lt;p&gt;제가생각하는 최대의 장점은 누구에게나 친숙한 자바스크립트 코드를 이용하여 native 앱을 제작할 수 있다는 점입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Front-End/ReactNative</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1035</guid>
      <comments>https://heeestorys.tistory.com/1035#entry1035comment</comments>
      <pubDate>Thu, 28 Nov 2019 14:12:59 +0900</pubDate>
    </item>
    <item>
      <title>[socket.io] 7. socket.io를 이용한 채팅프로그램 - 타이핑중추가</title>
      <link>https://heeestorys.tistory.com/1034</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 타인의 타이핑 확인&lt;/h3&gt;
&lt;p&gt;채팅을 하다보면 누군가가 글을 입력하고 있다는 알림을 보신적이 있습니다. 특히 slack을 애용하신다면 자주 보셨을 거라 생각합니다. 이번에는 저희가 만든 채팅프로그램에 누군가 입력중이라는 표시를 추가해보도록 하겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 클라이언트 socket&lt;/h3&gt;
&lt;p&gt;index.html&lt;/p&gt;
&lt;pre id=&quot;code_1574914494160&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Socket.IO chat&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
      #nick { position: absolute; right: 0; top: 0;}
      #typing { position: absolute; right: 0; bottom: 80px; outline: 1px solid green}
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;ul id=&quot;messages&quot;&amp;gt;&amp;lt;/ul&amp;gt;
    &amp;lt;form action=&quot;&quot;&amp;gt;
      &amp;lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&amp;gt;&amp;lt;button&amp;gt;Send&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
      &amp;lt;input id=&quot;nick&quot; placeholder=&quot;Enter your name&quot;/&amp;gt;
    &amp;lt;div id=&quot;typing&quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;https://code.jquery.com/jquery-1.11.1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      $(function () {
        var socket = io();
        $('form').submit(function(e){
          e.preventDefault(); // prevents page reloading
          socket.emit('chat message', $('#nick').val() + ':' +$('#m').val());
          $('#m').val('');
          return false;
        });
        socket.on('chat message', function(msg){
           $('#messages').append($('&amp;lt;li&amp;gt;').text(msg));
         });
        socket.on('typing', function(msg){
            $('#typing').text(msg);
         });
        $('#m').on('keyup', function(e){
          if (e.target.value) {
            socket.emit('typing', $('#nick').val());
          }
        })
      });
    &amp;lt;/script&amp;gt;

  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- &amp;lt;div id=&quot;typing&quot;&amp;gt;&amp;lt;/div&amp;gt;: 타이핑중이라는 표시를 해줄 태그를 추가했습니다.&lt;br /&gt;- keyup 이벤트: 기존 인풋 박스에 keyup 이벤트를 생성하여 키보드입력이 있을시 서버소켓으로 타이핑중인 nickname을 날립니다.&lt;br /&gt;- socket.on('typing'): 서버에서 받아온 typing 관련 메시지를 태그에 출력합니다&lt;br /&gt;- #typing: 태그에 스타일을 추가합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 서버 socket&lt;/h3&gt;
&lt;p&gt;index.js&lt;/p&gt;
&lt;pre id=&quot;code_1574914691210&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
	socket.broadcast.emit('chat message', 'user connection...');
	socket.on('chat message', function(msg){
		socket.broadcast.emit('typing', '');
		io.emit('chat message', msg);
	});
	socket.on('disconnect', function(){
		socket.broadcast.emit('chat message', 'user disconnection...');
	});
	socket.on('typing', function(msg){
		if(msg !== '') {
			socket.broadcast.emit('typing', msg + ' is typing...');
		}
	});
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- socket.on('typing'): 클라이언트에서 오는 typing 메시지를 리슨하고 있습니다. 그리고 broadcast를 통해 저를 제외한 다른 사람들에게 타이핑 중이라는 메시지를 보냅니다.&lt;br /&gt;- 입력을 끝내고 send를 눌렀을때 받는 chat message 이벤트에 typing 메시지값을 '' 로 전송하여 타이핑이 끝났음을 클라이언트에게 표시합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfgNVI/btqz258Icl2/OYYL8truR3WiJlJMOQtbAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfgNVI/btqz258Icl2/OYYL8truR3WiJlJMOQtbAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfgNVI/btqz258Icl2/OYYL8truR3WiJlJMOQtbAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfgNVI%2Fbtqz258Icl2%2FOYYL8truR3WiJlJMOQtbAk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 화면처럼 잘 나왔다면 성공입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 마무리&lt;/h3&gt;
&lt;p&gt;조금 아쉬운 부분은 socket.io api 문서를 참고하여 더욱 다양한 기능을 앞으로 추가해야될것 같습니다.&lt;/p&gt;</description>
      <category>Front-End/socket.io</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1034</guid>
      <comments>https://heeestorys.tistory.com/1034#entry1034comment</comments>
      <pubDate>Thu, 28 Nov 2019 13:22:43 +0900</pubDate>
    </item>
    <item>
      <title>[socket.io] 6. socket.io를 이용한 채팅프로그램 - 닉네임추가</title>
      <link>https://heeestorys.tistory.com/1033</link>
      <description>&lt;p style=&quot;font-size: 0.87em;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;i&gt;&lt;b&gt;socket.io 글들을 순차적으로 진행하시면 socket.io를 이해하는데 더욱 도움이 됩니다&lt;/b&gt;&lt;/i&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 닉네임추가&lt;/h3&gt;
&lt;p&gt;기존에 완성했던 채팅창에는 누구의 글인지 알 수가 없었습니다. 이제는 닉네임을 추가해서 조금더 채팅창 처럼 보이도록 하겠습니다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 클라이언트 socket.io&lt;/h3&gt;
&lt;p&gt;index.html&lt;/p&gt;
&lt;pre id=&quot;code_1574820825135&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;style&amp;gt;
...
#nick { position: absolute; right: 0; top: 0;}
&amp;lt;/style&amp;gt;

&amp;lt;body&amp;gt;
    &amp;lt;ul id=&quot;messages&quot;&amp;gt;&amp;lt;/ul&amp;gt;
    &amp;lt;form action=&quot;&quot;&amp;gt;
      &amp;lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&amp;gt;&amp;lt;button&amp;gt;Send&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
      &amp;lt;input id=&quot;nick&quot; placeholder=&quot;Enter your name&quot;/&amp;gt;// 닉네임 form 추가
    &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;https://code.jquery.com/jquery-1.11.1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      $(function () {
        var socket = io();
        $('form').submit(function(e){
          e.preventDefault(); // prevents page reloading
          socket.emit('chat message', $('#nick').val() + ':' +$('#m').val());
          $('#m').val('');
          return false;
        });
        socket.on('chat message', function(msg){
           $('#messages').append($('&amp;lt;li&amp;gt;').text(msg));
         });
      });
    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- 먼저 닉네임을 만들 input 박스를 추가합니다.&lt;br /&gt;- socket.emit() 부분에 닉네임을 포함한 msg 를 만들어 전송합니다&lt;br /&gt;- style 부분에 저희가 만든 input에 absolute 포지션을 추가합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EdypJ/btqz3oZ9qgP/kaSnppyxwqHMkX1Nj3gNNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EdypJ/btqz3oZ9qgP/kaSnppyxwqHMkX1Nj3gNNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EdypJ/btqz3oZ9qgP/kaSnppyxwqHMkX1Nj3gNNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEdypJ%2Fbtqz3oZ9qgP%2FkaSnppyxwqHMkX1Nj3gNNK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 테스트&lt;/h3&gt;
&lt;p&gt;창을 여러게 열고 이름을 입력해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2rnfr/btqz4iLSTFv/A25jNpOdZpqZHvD6kmqvY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2rnfr/btqz4iLSTFv/A25jNpOdZpqZHvD6kmqvY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2rnfr/btqz4iLSTFv/A25jNpOdZpqZHvD6kmqvY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2rnfr%2Fbtqz4iLSTFv%2FA25jNpOdZpqZHvD6kmqvY1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이름이 잘 노출되나요??? 위와같이 나왔다면 성공입니다.&lt;br /&gt;저는 클라이언트 사이드에서 임의로 닉네임을 추가했지만 만약 서버에 회원정보가 있다면 서버에서 클라이언트로 아이디를 추가해서 내려주는 구조로 만드는것이 좋을 것 같습니다.&lt;/p&gt;</description>
      <category>Front-End/socket.io</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1033</guid>
      <comments>https://heeestorys.tistory.com/1033#entry1033comment</comments>
      <pubDate>Wed, 27 Nov 2019 11:20:11 +0900</pubDate>
    </item>
    <item>
      <title>[socket.io] 5. socket.io를 이용한 채팅프로그램 - 유저접속추가</title>
      <link>https://heeestorys.tistory.com/1032</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 다른유저가 접속했는지 확인&lt;/h3&gt;
&lt;p&gt;앞의 소스들은 다른 소켓(클라이언트)이 접속을 했는지 않했는지 확인을 할 수 없었습니다.&amp;nbsp;&lt;br /&gt;이번 장에서는 socket.broadcast를 이용하여 접속 여부를 기능을 추가해보도록 하겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 서버 소켓&lt;/h3&gt;
&lt;p&gt;index.js&lt;/p&gt;
&lt;pre id=&quot;code_1574756865206&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
	socket.broadcast.emit('chat message', 'user connection...');
	socket.on('chat message', function(msg){
		io.emit('chat message', msg);
	});
	socket.on('disconnect', function(){
		socket.broadcast.emit('chat message', 'user disconnection...');
	});
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- 앞의 소스와 유사합니다. 단지 소켓 이벤트를 받는 부분에 집중해주세요&lt;br /&gt;- 처음 접속했다면 socket.broadcast를 이용하여 자신을 제외한 다른 클라이언트들에게 접속 여부를 알립니다.&lt;br /&gt;- socket.on('disconnect') : 해당 함수로 소켓 통신이 끝났는지 확인 할 수 있습니다. 이곳에다 위와같은 작업을 추가합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 확인&lt;/h3&gt;
&lt;pre id=&quot;code_1574756988387&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node index.js

localhost:3000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;서버를 가동하고 localhost:3000으로 접속해주세요. 그리고 이후에 창을 하나더 띄워주세요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C2GNB/btqz3nzKl5u/m1Cj4fikerhK9aGPIVMX90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C2GNB/btqz3nzKl5u/m1Cj4fikerhK9aGPIVMX90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C2GNB/btqz3nzKl5u/m1Cj4fikerhK9aGPIVMX90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC2GNB%2Fbtqz3nzKl5u%2Fm1Cj4fikerhK9aGPIVMX90%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;다시 브라우저 하나를 닫아주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2UX9g/btqz0B0K3lA/MHHTJIWEAHJFFGAAngkpi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2UX9g/btqz0B0K3lA/MHHTJIWEAHJFFGAAngkpi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2UX9g/btqz0B0K3lA/MHHTJIWEAHJFFGAAngkpi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2UX9g%2Fbtqz0B0K3lA%2FMHHTJIWEAHJFFGAAngkpi0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위와같이 나왔다면 성공입니다 :)&lt;/p&gt;
&lt;p&gt;다음은 접속 유저의 닉네임을 추가해보도록 하겠습니다.&lt;/p&gt;</description>
      <category>Front-End/socket.io</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1032</guid>
      <comments>https://heeestorys.tistory.com/1032#entry1032comment</comments>
      <pubDate>Tue, 26 Nov 2019 17:33:27 +0900</pubDate>
    </item>
    <item>
      <title>[socket.io] 4. socket.io를 이용한 채팅프로그램 - 이벤트처리 &amp;amp; 채팅완성</title>
      <link>https://heeestorys.tistory.com/1031</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 이벤트 발생&lt;/h3&gt;
&lt;p&gt;앞의 예제에서 socket.io를 연동하고 클라이언트에서 채팅창을 구현했습니다. 또한 클라이언트가 소켓을 연결헀을때 서버 로그로 접속되는것 까지 확인했습니다. 이번에는 클라이언트에서 발생한 이벤트를 서버로 전달하겠습니다.&lt;/p&gt;
&lt;p&gt;예를들어 클라이언트 입력폼에 메시지를 submit 하면 서버에서 해당메시지를 받는지 확인하겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 클라이언트 설정&lt;/h3&gt;
&lt;p&gt;index.html&lt;/p&gt;
&lt;pre id=&quot;code_1574748006830&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;ul id=&quot;messages&quot;&amp;gt;&amp;lt;/ul&amp;gt;
    &amp;lt;form action=&quot;&quot;&amp;gt;
      &amp;lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&amp;gt;&amp;lt;button&amp;gt;Send&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
    &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;https://code.jquery.com/jquery-1.11.1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      $(function () {
        var socket = io();
        $('form').submit(function(e){
          e.preventDefault(); // prevents page reloading
          socket.emit('chat message', $('#m').val());
          $('#m').val('');
          return false;
        });
      });
    &amp;lt;/script&amp;gt;
    
  &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;기존에 작성했던 클라이언트 코드 &amp;lt;script&amp;gt; 부분을 위와같이 추가합니다.&lt;br /&gt;- socket.emit() : 첫번째 변수가 key 값이 됩니다. server 소켓에서 이벤트를 감지할 경우 해당 키값으로 이벤트를 listen 합니다. 두번째 변수는 value 를 전달합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 서버설정&lt;/h3&gt;
&lt;p&gt;index.js&lt;/p&gt;
&lt;pre id=&quot;code_1574748555935&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket) {
	socket.on('chat message', function(msg){
		console.log('message: '+msg);
	})
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- socket.on(): 첫번째 변수는 키값으로 클라이언트에서 소켓 이벤트를 발생시켰을때 연결됩니다. 두번쨰 변수의 함수는 콜백함수로 클라이언트에서 넘어온 변수값을 받습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;643&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buexhn/btqz042vkBe/aXNhoo5pSDbakzoD7j6q81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buexhn/btqz042vkBe/aXNhoo5pSDbakzoD7j6q81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buexhn/btqz042vkBe/aXNhoo5pSDbakzoD7j6q81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbuexhn%2Fbtqz042vkBe%2FaXNhoo5pSDbakzoD7j6q81%2Fimg.png&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;643&quot; data-filename=&quot;blob&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위와 같이 localhost:3000으로 접속하여 채팅창에 값을 입력후 send를 누루면 서버 창에 log로 저희가 입력한 값들이 출력됩니다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 브로드캐스트&lt;/h3&gt;
&lt;p&gt;서버로 받은 메시지를 이젠 다른 클라이언트들이 공유할 수 있도록 브로드캐스트 해보겠습니다.&lt;/p&gt;
&lt;p&gt;index.html&lt;/p&gt;
&lt;pre id=&quot;code_1574751271555&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; &amp;lt;body&amp;gt;
    &amp;lt;ul id=&quot;messages&quot;&amp;gt;&amp;lt;/ul&amp;gt;
    &amp;lt;form action=&quot;&quot;&amp;gt;
      &amp;lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&amp;gt;&amp;lt;button&amp;gt;Send&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
    &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;https://code.jquery.com/jquery-1.11.1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      $(function () {
        var socket = io();
        $('form').submit(function(e){
          e.preventDefault(); // prevents page reloading
          socket.emit('chat message', $('#m').val());
          $('#m').val('');
          return false;
        });
        socket.on('chat message', function(msg){
           $('#messages').append($('&amp;lt;li&amp;gt;').text(msg));
         });
      });
    &amp;lt;/script&amp;gt;

  &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- socket.on() : 서버에서 요청하는 이벤트를 listen 하는 역할을하며 데이터를 받아와 클라이언트에 노출시키는 작업을 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;index.js&lt;/p&gt;
&lt;pre id=&quot;code_1574751754297&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- socket.on(): 다른 소켓(클라이언트)온 이벤트를 처리합니다&lt;br /&gt;- io.emit() : 해당함수를 이용하여 서버에 데이터를 연결된 소켓으로 전달하는 역할을 합니다. 저희가 만들려면 채팅프로그램의 핵심입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574751845023&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;서버를 활성화 시킨후 localhost:3000 브라우저를 여러개 띄워주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhWQrp/btqzZ2qx8kP/4bahw82EQryGahaCBdwnv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhWQrp/btqzZ2qx8kP/4bahw82EQryGahaCBdwnv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhWQrp/btqzZ2qx8kP/4bahw82EQryGahaCBdwnv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhWQrp%2FbtqzZ2qx8kP%2F4bahw82EQryGahaCBdwnv0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;- 위 화면처럼 입력을 하면 양쪽의 브라우저에서 모두 노출되나요? 그렇다면 성공입니다. :)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 나를 제외한 클라이언트에게 브로드캐스팅&lt;/h3&gt;
&lt;pre id=&quot;code_1574754749201&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;socket.broadcast.emit('chat message', 'hi');&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;socket.broadcast: 나를 제외한 다른 사람에게만 브로드캐스팅합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1574754792423&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
	socket.broadcast.emit('chat message', 'hi');
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- 저희가 작업한 server 소스중에 이벤트 리슨하는부분을 위와같이 변경해주세요.&lt;br /&gt;이후에 localhost:3000을 하나씩 띄운다면 기존에 있던 창에 hi가 출력되는것을 볼 수 있습니다.&lt;/p&gt;</description>
      <category>Front-End/socket.io</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1031</guid>
      <comments>https://heeestorys.tistory.com/1031#entry1031comment</comments>
      <pubDate>Tue, 26 Nov 2019 15:21:08 +0900</pubDate>
    </item>
    <item>
      <title>[socket.io] 3. socket.io를 이용한 채팅프로그램 - socket.io 연동</title>
      <link>https://heeestorys.tistory.com/1030</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. socket.io 구성&lt;/h2&gt;
&lt;p&gt;socket.io는 두 가지로 구성됩니다&lt;/p&gt;
&lt;p&gt;- socket.io : 서버에서 사용되는 모듈 입니다.&lt;/p&gt;
&lt;p&gt;- socket.io-client: 브라우저에서 사용되는 모듈입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. socket.io 설치&lt;/h2&gt;
&lt;p&gt;npm을 이용해 설치하겠습니다&lt;/p&gt;
&lt;pre id=&quot;code_1574656539180&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install socket.io&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 서버 socket.io&lt;/h3&gt;
&lt;p&gt;index.js&lt;/p&gt;
&lt;pre id=&quot;code_1574656586243&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket) {
	console.log('a user connected');
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- socket.io를 require 받은 후 .on 함수로 connection 이벤트를 연결합니다.&lt;br /&gt;- socket.io 변수로 http 객체를 전달받았습니다.&lt;br /&gt;- 이제 서버로 들어오는 socket연결들을 리스닝 할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 클라이언트 socket.io-client&lt;/h3&gt;
&lt;pre id=&quot;code_1574656774982&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      var socket = io();
    &amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;-&amp;nbsp; &amp;lt;/body&amp;gt; 태그 이전에 위와같이 등록합니다.&amp;nbsp;&lt;br /&gt;- io() 함수가 글로벌하게 등록되었습니다. 클라이언트에 로드되는 모든 브라우저 소켓에 작동합니다&lt;br /&gt;- 만약 글로벌보다는 로컬버전으로 사용하게 하고싶다면 node_modules/socket.io-client/dist/socket.io.js연결하면 됩니다&lt;br /&gt;- io() 안에 특정한 url을 등록하지 않았습니다. url을 등록하지 않았다면 자동적으로 서버 호스트로 연결합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. socket.io 실행&lt;/h2&gt;
&lt;p&gt;위의 과정을 했다면 노드서버를 다시 작동시키겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574657221330&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 브라우저 창에 localhost:3000으로 접속합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbFJTe/btqzZ15alAN/Pr2rI3eqgXlWBabbsn5NZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbFJTe/btqzZ15alAN/Pr2rI3eqgXlWBabbsn5NZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbFJTe/btqzZ15alAN/Pr2rI3eqgXlWBabbsn5NZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbFJTe%2FbtqzZ15alAN%2FPr2rI3eqgXlWBabbsn5NZk%2Fimg.png&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;702&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;localhost:3000으로 접속했을때 커맨드라인에 a user connected 가 출력됬다면 소켓이 연결된 것입니다. 여러 창을 띄워볼까요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c23F4l/btqz0AzvUSr/Poqdshyk9k4VEpcI3weLQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c23F4l/btqz0AzvUSr/Poqdshyk9k4VEpcI3weLQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c23F4l/btqz0AzvUSr/Poqdshyk9k4VEpcI3weLQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc23F4l%2Fbtqz0AzvUSr%2FPoqdshyk9k4VEpcI3weLQK%2Fimg.png&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;706&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;창을 두개 띄웠더니 a user connected 가 두개 생성되었습니다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. socket.io 연결끊기 추가&lt;/h2&gt;
&lt;p&gt;위 상태에서 브라우저창을 닫으면 터미널에 아무것도 출력되지 않습니다. 이제 소켓연결이 끊어진것도 추가하겠습니다&lt;/p&gt;
&lt;pre id=&quot;code_1574657472732&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket) {
	console.log('a user connected');
	socket.on('disconnect', function() {
		console.log('user disconnected');
	});
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- io.on 함수에 disconnect 이벤트를 추가했습니다&lt;/p&gt;
&lt;p&gt;다시 서버를 재가동한후 localhost:3000에 접속했다가 브라우저를 닫아 보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;167&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/plY5v/btqzYDxDeuq/ppb85qZIzuTHyntR9GmK3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/plY5v/btqzYDxDeuq/ppb85qZIzuTHyntR9GmK3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/plY5v/btqzYDxDeuq/ppb85qZIzuTHyntR9GmK3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FplY5v%2FbtqzYDxDeuq%2Fppb85qZIzuTHyntR9GmK3K%2Fimg.png&quot; data-origin-width=&quot;167&quot; data-origin-height=&quot;67&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위와같이 연결이 끊겼다고 나오면 성공입니다.&lt;/p&gt;
&lt;p&gt;다음에는 드디어 채팅창을 만들어 보도록 하겠습니다. 예전에 c언어로 작성했던 채팅 소스와 비교하니 감개무량합니다&amp;nbsp;&lt;br /&gt;:)&lt;/p&gt;</description>
      <category>Front-End/socket.io</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1030</guid>
      <comments>https://heeestorys.tistory.com/1030#entry1030comment</comments>
      <pubDate>Mon, 25 Nov 2019 13:32:57 +0900</pubDate>
    </item>
    <item>
      <title>[socket.io] 2. socket.io를 이용한 채팅프로그램 - 프로젝트 설정</title>
      <link>https://heeestorys.tistory.com/1029</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 에디터, 서버와 클라이언트 셋팅&lt;/h3&gt;
&lt;p&gt;블로그에서 만드는 채팅프로그램은 socket.io 스타터 프로젝트를 재현합니다. 재현하면서 발생하는 문제를 기록하고 프로젝트 마지막에 있는 남은 과제또한 수행하는것이 목적입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://socket.io/get-started/chat/&quot;&gt;https://socket.io/get-started/chat/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1574313719591&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Socket.IO  &amp;mdash;  Chat&quot; data-og-description=&quot;In this guide we&amp;rsquo;ll create a basic chat application. It requires almost no basic prior knowledge of Node.JS or Socket.IO, so it&amp;rsquo;s ideal for users of all knowledge levels. IntroductionWriting a chat ap&quot; data-og-host=&quot;socket.io&quot; data-og-source-url=&quot;https://socket.io/get-started/chat/&quot; data-og-url=&quot;https://socket.io/get-started/chat/index.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/egE2e8/hyDNjUwOhR/cdP6ZGElxWxXkDRoZ8fRck/img.png?width=572&amp;amp;height=350&amp;amp;face=0_0_572_350,https://scrap.kakaocdn.net/dn/gNjbz/hyDNb92T2L/vm02Xq3J0fU2NbN3QYzHYk/img.png?width=636&amp;amp;height=462&amp;amp;face=0_0_636_462,https://scrap.kakaocdn.net/dn/claLrR/hyDNiVDd7H/kPexcYQuEmZ57YdFK8hc31/img.png?width=635&amp;amp;height=463&amp;amp;face=0_0_635_463,https://scrap.kakaocdn.net/dn/bJJ8uJ/hyDNdmttuT/6Oq73KUY96TeEwzRHNkS01/img.png?width=572&amp;amp;height=350&amp;amp;face=0_0_572_350&quot;&gt;&lt;a href=&quot;https://socket.io/get-started/chat/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://socket.io/get-started/chat/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/egE2e8/hyDNjUwOhR/cdP6ZGElxWxXkDRoZ8fRck/img.png?width=572&amp;amp;height=350&amp;amp;face=0_0_572_350,https://scrap.kakaocdn.net/dn/gNjbz/hyDNb92T2L/vm02Xq3J0fU2NbN3QYzHYk/img.png?width=636&amp;amp;height=462&amp;amp;face=0_0_636_462,https://scrap.kakaocdn.net/dn/claLrR/hyDNiVDd7H/kPexcYQuEmZ57YdFK8hc31/img.png?width=635&amp;amp;height=463&amp;amp;face=0_0_635_463,https://scrap.kakaocdn.net/dn/bJJ8uJ/hyDNdmttuT/6Oq73KUY96TeEwzRHNkS01/img.png?width=572&amp;amp;height=350&amp;amp;face=0_0_572_350');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Socket.IO &amp;mdash; Chat&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;In this guide we&amp;rsquo;ll create a basic chat application. It requires almost no basic prior knowledge of Node.JS or Socket.IO, so it&amp;rsquo;s ideal for users of all knowledge levels. IntroductionWriting a chat ap&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;socket.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;socket.io를 알고싶다면 저와함께 프로젝트를 조금씩 진행하시기를 추천드립니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 프로젝트 셋팅&lt;/h3&gt;
&lt;p&gt;- 에디터: intellij&lt;/p&gt;
&lt;p&gt;- OS: 윈도우 10&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) 서버만들기&lt;/h4&gt;
&lt;p&gt;기본적으로 NPM 을 사용하여 서버를 셋팅하고 서버는 node, express 를 사용합니다.&lt;/p&gt;
&lt;p&gt;프로젝트 폴더에 npm 을 설치해주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1574314061698&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그리고 express를 설치합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574314148512&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install express&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;express는 노드서버를 만들때 더욱 쉽게 만들수 있는 패키지입니다.&lt;/p&gt;
&lt;p&gt;root 디렉토리에 index.js 파일을 하나 만들고 아래와 같이 작성해주세요&lt;/p&gt;
&lt;pre id=&quot;code_1574314299933&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var app = require('express')();
var http = require('http').createServer(app);

app.get('/', function(req, res){
  res.send('&amp;lt;h1&amp;gt;Hello world&amp;lt;/h1&amp;gt;');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- app.get('/') : 서버라우터 역할을 합니다. /을 통해서 들어온 요청은 해당 get 함수를 실행시킵니다.&lt;br /&gt;- res.send(): 서버렌더링으로 브라우제어 &amp;lt;h1&amp;gt; 태그를 출력합니다.&lt;/p&gt;
&lt;p&gt;mac이라면 터미널을 이용하여 node index.js 를 입력하세요. 윈도우라는 cmd 저는 intellij 터미널에서 입력하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574315099473&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;33&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rIvL8/btqzTDqITBJ/1lfFMzIm6kpSzR5me3LaaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rIvL8/btqzTDqITBJ/1lfFMzIm6kpSzR5me3LaaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rIvL8/btqzTDqITBJ/1lfFMzIm6kpSzR5me3LaaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrIvL8%2FbtqzTDqITBJ%2F1lfFMzIm6kpSzR5me3LaaK%2Fimg.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;33&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위의 이미지처럼 서버가 잘 켜졌나요?&lt;br /&gt;이제 브라우저에 localhost:3000으로 접속해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;304&quot; data-origin-height=&quot;111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DPihB/btqzUPqJQyN/GqTkuOZMpkqEkftVeKYWJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DPihB/btqzUPqJQyN/GqTkuOZMpkqEkftVeKYWJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DPihB/btqzUPqJQyN/GqTkuOZMpkqEkftVeKYWJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDPihB%2FbtqzUPqJQyN%2FGqTkuOZMpkqEkftVeKYWJ0%2Fimg.png&quot; data-origin-width=&quot;304&quot; data-origin-height=&quot;111&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위와 같이 브라우저에 표시됬다면 성공입니다. 이젠 Hello world 가 아닌 그럴듯한 채팅 창으로 렌더링 하겠습니다. socket.io 사이트 예제에 있는 마크업을 그대로 복붙하겠습니다. 그전에 root 디렉토리에 index.html 파일을 만들어 주세요.&lt;/p&gt;
&lt;p&gt;index.html&lt;/p&gt;
&lt;pre id=&quot;code_1574315405274&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Socket.IO chat&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;ul id=&quot;messages&quot;&amp;gt;&amp;lt;/ul&amp;gt;
    &amp;lt;form action=&quot;&quot;&amp;gt;
      &amp;lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&amp;gt;&amp;lt;button&amp;gt;Send&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그리고 node 서버도 해당 파일을 불러서 화면에 렌더링 할수 있도록 index.js 파일도 수정하겠습니다.&lt;/p&gt;
&lt;p&gt;index.js&lt;/p&gt;
&lt;pre id=&quot;code_1574315462425&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const app = require('express')();
const http = require('http').createServer(app);

app.get('/', function(req, res){
	res.sendFile(__dirname + '/index.html');
});

http.listen(3000, function () {
	console.log('listening on*: 3000');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- sendFile() : 노드에서 프로젝트 경로에있는 특정 파일을 찾아 클라이언트 브라우저로 내려주는 역할을 합니다.&amp;nbsp;&lt;br /&gt;__dirname은 루트경로를 의미합니다.&lt;/p&gt;
&lt;p&gt;변경한상태에서 서버를 다시 재가동해주세요. 그리고 다시한번 localhost:3000으로 접속합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eop6c7/btqzS0NkgN1/JaCPkVQdMCeKnTkglP28k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eop6c7/btqzS0NkgN1/JaCPkVQdMCeKnTkglP28k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eop6c7/btqzS0NkgN1/JaCPkVQdMCeKnTkglP28k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feop6c7%2FbtqzS0NkgN1%2FJaCPkVQdMCeKnTkglP28k0%2Fimg.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;448&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위와같이 화면이 나왔다면 성공입니다. 아직까진 어려울게 없네요.&lt;br /&gt;다음 장에서는 드디어 socket,io를 연동해보도록 하겠습니다.&lt;/p&gt;</description>
      <category>Front-End/socket.io</category>
      <author>리딩리드</author>
      <guid isPermaLink="true">https://heeestorys.tistory.com/1029</guid>
      <comments>https://heeestorys.tistory.com/1029#entry1029comment</comments>
      <pubDate>Thu, 21 Nov 2019 14:34:42 +0900</pubDate>
    </item>
  </channel>
</rss>