From 42960a6fba5024dffb551aabc8e54b581c5c81f6 Mon Sep 17 00:00:00 2001 From: hzoou Date: Tue, 17 Dec 2019 19:04:32 +0900 Subject: [PATCH 01/10] =?UTF-8?q?chore:=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20=ED=99=98=EA=B2=BD=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 소켓 통신을 위해 socket.io와 diff 알고리즘을 설치하였습니다. --- live-server/.gitignore | 138 +++++++++++++++++++ live-server/package.json | 16 +++ live-server/yarn.lock | 287 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 441 insertions(+) create mode 100644 live-server/.gitignore create mode 100644 live-server/package.json create mode 100644 live-server/yarn.lock diff --git a/live-server/.gitignore b/live-server/.gitignore new file mode 100644 index 00000000..38ff8eb7 --- /dev/null +++ b/live-server/.gitignore @@ -0,0 +1,138 @@ +# Created by https://www.gitignore.io/api/intellij,webstorm +# Edit at https://www.gitignore.io/?templates=intellij,webstorm + +# Dependency directories +node_modules/ + +# env +env.tar + +### Intellij & WebStorm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/ +.idea/**/workspace.xml +.idea/**/tasks.xmlgit +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ + +### VSCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Created by https://www.gitignore.io/api/macos +# Edit at https://www.gitignore.io/?templates=macos + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# End of https://www.gitignore.io/api/macos% diff --git a/live-server/package.json b/live-server/package.json new file mode 100644 index 00000000..7514849a --- /dev/null +++ b/live-server/package.json @@ -0,0 +1,16 @@ +{ + "name": "live-server", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "nodemon app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "diff": "^4.0.1", + "socket.io": "^2.3.0" + } +} diff --git a/live-server/yarn.lock b/live-server/yarn.lock new file mode 100644 index 00000000..0cbe246d --- /dev/null +++ b/live-server/yarn.lock @@ -0,0 +1,287 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.4: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64id@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +diff@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" + integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== + +engine.io-client@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" + integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~4.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.4.0.tgz#3a962cc4535928c252759a00f98519cb46c53ff3" + integrity sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "0.3.1" + debug "~4.1.0" + engine.io-parser "~2.2.0" + ws "^7.1.2" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +mime-db@1.42.0: + version "1.42.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" + integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== + +mime-types@~2.1.24: + version "2.1.25" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" + integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== + dependencies: + mime-db "1.42.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +socket.io-adapter@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" + integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== + +socket.io-client@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~4.1.0" + engine.io-client "~3.4.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.0.tgz#370bb4a151df2f77ce3345ff55a7072cc6e9565a" + integrity sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ== + dependencies: + component-emitter "1.2.1" + debug "~4.1.0" + isarray "2.0.1" + +socket.io@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.3.0.tgz#cd762ed6a4faeca59bc1f3e243c0969311eb73fb" + integrity sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg== + dependencies: + debug "~4.1.0" + engine.io "~3.4.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.3.0" + socket.io-parser "~3.4.0" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +ws@^7.1.2: + version "7.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" + integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== + +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= From 5c5763e1317ac92606b415041a0c2f129733bc0e Mon Sep 17 00:00:00 2001 From: hzoou Date: Wed, 18 Dec 2019 16:04:07 +0900 Subject: [PATCH 02/10] =?UTF-8?q?chore:=20=ED=94=84=EB=A6=AC=ED=8B=B0?= =?UTF-8?q?=EC=96=B4=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 프리티어를 설정했습니다. --- live-server/.prettierrc | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 live-server/.prettierrc diff --git a/live-server/.prettierrc b/live-server/.prettierrc new file mode 100644 index 00000000..4ad6706f --- /dev/null +++ b/live-server/.prettierrc @@ -0,0 +1,10 @@ +{ + "printWidth": 80, + "tabWidth": 4, + "useTabs": true, + "semi": true, + "singleQuote": true, + "trailingComma": "none", + "bracketSpacing": true, + "arrowParens": "avoid" +} From 94f2b519d5f5859821fecdbae078b2f9f8402d5a Mon Sep 17 00:00:00 2001 From: hzoou Date: Wed, 18 Dec 2019 18:04:26 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feat:=20=EC=86=8C=EC=BC=93=20=EB=A3=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 클라이언트에서 룸을 생성해달라는 요청이 온 경우 프로젝트 아이디로 소켓 룸을 생성했습니다. --- live-server/app.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 live-server/app.js diff --git a/live-server/app.js b/live-server/app.js new file mode 100644 index 00000000..a8c6cd20 --- /dev/null +++ b/live-server/app.js @@ -0,0 +1,49 @@ +const io = require('socket.io')(); +const port = 3040; + +const rooms = {}; + +io.on('connection', socket => { + const isNotHost = (host, username) => host.username !== username; + const isFirstVisit = (participants, username) => indexOfUser(participants, username) === -1; + const indexOfUser = (participants, username) => + participants.findIndex(participant => participant.username === username); + + const HandleCreateRoom = ({ projectId, user, project }) => { + socket.user = user; + socket.room = projectId; + socket.join(projectId); + + if (rooms[projectId]) { // 방에 참여하는 경우 + const room = rooms[socket.room]; + const { host, participants } = room; + const { user: { username }} = socket; + + // 호스트 혹은 이미 접속한 사람이 재접속했을 때 참가자에 추가되는 것을 방지 + if (isNotHost(host, username) && isFirstVisit(participants, username)) + participants.push(socket.user); + + // 본인에게 알리기 + io.to(socket.id).emit('alreadyExistRoom', { host, project }); + } else { // 방을 생성하는 경우 + rooms[projectId] = {}; + rooms[projectId]['host'] = user; + rooms[projectId]['project'] = project; + rooms[projectId]['participants'] = []; + + // 본인에게 알리기 + io.to(socket.id).emit('successCreatedRoom', { project }); + } + + const room = rooms[socket.room]; + const { participants } = room; + + // 해당 방에 있는 사람들에게 알리기 + io.in(socket.room).emit('joinUser', { participants }); + }; + + socket.emit('connected'); + socket.on('createRoom', HandleCreateRoom); +}); + +io.listen(port); \ No newline at end of file From d1382c41c43b90c823c754840ca927cae2a4376a Mon Sep 17 00:00:00 2001 From: hzoou Date: Wed, 18 Dec 2019 18:09:15 +0900 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20=EC=86=8C=EC=BC=93=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=EC=9D=B4=20=EB=81=8A=EC=96=B4=EC=A1=8C=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 소켓 연결이 끊긴 경우 호스트와 일반 유저에 따라 다르게 처리했습니다. 호스트가 연결이 끊긴 경우에는 해당 소켓의 연결을 닫도록 구현하였고, 게스트가 나간 경우에는 참여 사용자 목록에서 해당 유저를 제거했습니다. --- live-server/app.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/live-server/app.js b/live-server/app.js index a8c6cd20..87c3503f 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -42,8 +42,25 @@ io.on('connection', socket => { io.in(socket.room).emit('joinUser', { participants }); }; + const handleDisconnect = () => { + const room = rooms[socket.room]; + if (!room) return; + const { host, participants } = room; + const { user: { username }} = socket; + socket.leave(socket.room); + + if (host.username === username) { // 호스트가 연결이 끊긴 경우 + rooms[socket.room] = null; + io.sockets.in(socket.room).emit('close'); + } else { // 게스트가 연결이 끊긴 경우 + participants.splice(indexOfUser(participants, username), 1); + io.in(socket.room).emit('leaveUser', { participants }); + } + }; + socket.emit('connected'); socket.on('createRoom', HandleCreateRoom); + socket.on('disconnect', handleDisconnect); }); io.listen(port); \ No newline at end of file From 7f0232d29451c2486fcbe3160235514aa1ee9331 Mon Sep 17 00:00:00 2001 From: hzoou Date: Wed, 18 Dec 2019 18:12:56 +0900 Subject: [PATCH 05/10] =?UTF-8?q?feat:=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=20?= =?UTF-8?q?=EC=A4=91=EC=A7=80=20=EC=9A=94=EC=B2=AD=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 호스트가 라이브를 중지하고자 요청을 보낸 경우, 해당 방에 있는 모든 유저에게 알리도록 구현했습니다. --- live-server/app.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/live-server/app.js b/live-server/app.js index 87c3503f..0d14c2c6 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -58,9 +58,15 @@ io.on('connection', socket => { } }; + const handleCloseSocket = () => { // 호스트가 라이브를 중지한 경우 + rooms[socket.room] = null; + io.sockets.in(socket.room).emit('close'); + }; + socket.emit('connected'); socket.on('createRoom', HandleCreateRoom); socket.on('disconnect', handleDisconnect); + socket.on('close', handleCloseSocket); }); io.listen(port); \ No newline at end of file From c312fc6b5912c9e986325fda106fe9af86ca3c6a Mon Sep 17 00:00:00 2001 From: hzoou Date: Wed, 18 Dec 2019 18:57:08 +0900 Subject: [PATCH 06/10] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 코드리뷰를 반영했습니다. --- live-server/app.js | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/live-server/app.js b/live-server/app.js index 0d14c2c6..2e66e819 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -1,5 +1,5 @@ const io = require('socket.io')(); -const port = 3040; +const PORT = 3040; const rooms = {}; @@ -9,14 +9,13 @@ io.on('connection', socket => { const indexOfUser = (participants, username) => participants.findIndex(participant => participant.username === username); - const HandleCreateRoom = ({ projectId, user, project }) => { + const handleCreateRoom = ({ projectId, user, project }) => { socket.user = user; socket.room = projectId; socket.join(projectId); if (rooms[projectId]) { // 방에 참여하는 경우 - const room = rooms[socket.room]; - const { host, participants } = room; + const { host, participants } = rooms[socket.room]; const { user: { username }} = socket; // 호스트 혹은 이미 접속한 사람이 재접속했을 때 참가자에 추가되는 것을 방지 @@ -24,28 +23,27 @@ io.on('connection', socket => { participants.push(socket.user); // 본인에게 알리기 - io.to(socket.id).emit('alreadyExistRoom', { host, project }); + socket.emit('alreadyExistRoom', { host, project }); } else { // 방을 생성하는 경우 - rooms[projectId] = {}; - rooms[projectId]['host'] = user; - rooms[projectId]['project'] = project; - rooms[projectId]['participants'] = []; + rooms[projectId] = { + host: user, + project, + participants: [] + }; // 본인에게 알리기 - io.to(socket.id).emit('successCreatedRoom', { project }); + socket.emit('successCreatedRoom', { project }); } - const room = rooms[socket.room]; - const { participants } = room; + const { participants } = rooms[socket.room]; // 해당 방에 있는 사람들에게 알리기 io.in(socket.room).emit('joinUser', { participants }); }; const handleDisconnect = () => { - const room = rooms[socket.room]; - if (!room) return; - const { host, participants } = room; + if (!rooms[socket.room]) return; + const { host, participants } = rooms[socket.room]; const { user: { username }} = socket; socket.leave(socket.room); @@ -64,7 +62,7 @@ io.on('connection', socket => { }; socket.emit('connected'); - socket.on('createRoom', HandleCreateRoom); + socket.on('createRoom', handleCreateRoom); socket.on('disconnect', handleDisconnect); socket.on('close', handleCloseSocket); }); From dc4a949797298e586d306265d83536a6087fe4d0 Mon Sep 17 00:00:00 2001 From: hzoou Date: Wed, 18 Dec 2019 19:06:25 +0900 Subject: [PATCH 07/10] =?UTF-8?q?fix:=20=EC=98=A4=ED=83=88=EC=9E=90=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 오탈자를 수정했습니다. --- live-server/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/live-server/app.js b/live-server/app.js index 2e66e819..a5f60b03 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -67,4 +67,4 @@ io.on('connection', socket => { socket.on('close', handleCloseSocket); }); -io.listen(port); \ No newline at end of file +io.listen(PORT); \ No newline at end of file From 907d685505c8c2947957f8a6c6b9380328268247 Mon Sep 17 00:00:00 2001 From: BasilToast <33782602+BasilToast@users.noreply.github.com> Date: Thu, 19 Dec 2019 01:16:03 +0900 Subject: [PATCH 08/10] =?UTF-8?q?feat:=20change=20=EC=9D=B4=EB=B2=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=98=EC=98=80?= =?UTF-8?q?=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기본적인 에디터를 공유할 수 있도록 최소한의 기능을 담은 핸들러를 추가하였습니다. --- live-server/app.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/live-server/app.js b/live-server/app.js index a5f60b03..812e894c 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -3,7 +3,10 @@ const PORT = 3040; const rooms = {}; +const userName = ['basil', 'unknown', 'yuk', 'lallaheee', 'hzoou']; + io.on('connection', socket => { + console.log('someone connectted'); const isNotHost = (host, username) => host.username !== username; const isFirstVisit = (participants, username) => indexOfUser(participants, username) === -1; const indexOfUser = (participants, username) => @@ -13,14 +16,18 @@ io.on('connection', socket => { socket.user = user; socket.room = projectId; socket.join(projectId); + if (rooms[projectId]) { // 방에 참여하는 경우 const { host, participants } = rooms[socket.room]; const { user: { username }} = socket; // 호스트 혹은 이미 접속한 사람이 재접속했을 때 참가자에 추가되는 것을 방지 - if (isNotHost(host, username) && isFirstVisit(participants, username)) + if (isNotHost(host, username) && isFirstVisit(participants, username)) { + if(!socket.user) socket.user = userName.pop(); participants.push(socket.user); + } + // 본인에게 알리기 socket.emit('alreadyExistRoom', { host, project }); @@ -61,10 +68,20 @@ io.on('connection', socket => { io.sockets.in(socket.room).emit('close'); }; + const handleOnChange = operation => { + io.in(socket.room).emit('change', socket.id, operation) + } + + const handleOnMoveCursor = position => { + socket.broadcast.emit('moveCursor', socket.user.username, position); + } + socket.emit('connected'); socket.on('createRoom', handleCreateRoom); socket.on('disconnect', handleDisconnect); socket.on('close', handleCloseSocket); + socket.on('change', handleOnChange); + socket.on('moveCursor', handleOnMoveCursor); }); io.listen(PORT); \ No newline at end of file From 3a7353c7af59ac9defc378d0d1f1aafa08780701 Mon Sep 17 00:00:00 2001 From: Basiltoast Date: Fri, 20 Dec 2019 00:19:25 +0900 Subject: [PATCH 09/10] =?UTF-8?q?feat:=20change,=20cursor=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 각 사용자가 입력한 내용을 서버에서 응답하도록 하였습니다. --- live-server/app.js | 174 +++++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 79 deletions(-) diff --git a/live-server/app.js b/live-server/app.js index 812e894c..8eefaeb0 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -3,85 +3,101 @@ const PORT = 3040; const rooms = {}; -const userName = ['basil', 'unknown', 'yuk', 'lallaheee', 'hzoou']; - io.on('connection', socket => { - console.log('someone connectted'); - const isNotHost = (host, username) => host.username !== username; - const isFirstVisit = (participants, username) => indexOfUser(participants, username) === -1; - const indexOfUser = (participants, username) => - participants.findIndex(participant => participant.username === username); - - const handleCreateRoom = ({ projectId, user, project }) => { - socket.user = user; - socket.room = projectId; - socket.join(projectId); - - - if (rooms[projectId]) { // 방에 참여하는 경우 - const { host, participants } = rooms[socket.room]; - const { user: { username }} = socket; - - // 호스트 혹은 이미 접속한 사람이 재접속했을 때 참가자에 추가되는 것을 방지 - if (isNotHost(host, username) && isFirstVisit(participants, username)) { - if(!socket.user) socket.user = userName.pop(); - participants.push(socket.user); - } - - - // 본인에게 알리기 - socket.emit('alreadyExistRoom', { host, project }); - } else { // 방을 생성하는 경우 - rooms[projectId] = { - host: user, - project, - participants: [] - }; - - // 본인에게 알리기 - socket.emit('successCreatedRoom', { project }); - } - - const { participants } = rooms[socket.room]; - - // 해당 방에 있는 사람들에게 알리기 - io.in(socket.room).emit('joinUser', { participants }); - }; - - const handleDisconnect = () => { - if (!rooms[socket.room]) return; - const { host, participants } = rooms[socket.room]; - const { user: { username }} = socket; - socket.leave(socket.room); - - if (host.username === username) { // 호스트가 연결이 끊긴 경우 - rooms[socket.room] = null; - io.sockets.in(socket.room).emit('close'); - } else { // 게스트가 연결이 끊긴 경우 - participants.splice(indexOfUser(participants, username), 1); - io.in(socket.room).emit('leaveUser', { participants }); - } - }; - - const handleCloseSocket = () => { // 호스트가 라이브를 중지한 경우 - rooms[socket.room] = null; - io.sockets.in(socket.room).emit('close'); - }; - - const handleOnChange = operation => { - io.in(socket.room).emit('change', socket.id, operation) - } - - const handleOnMoveCursor = position => { - socket.broadcast.emit('moveCursor', socket.user.username, position); - } - - socket.emit('connected'); - socket.on('createRoom', handleCreateRoom); - socket.on('disconnect', handleDisconnect); - socket.on('close', handleCloseSocket); - socket.on('change', handleOnChange); - socket.on('moveCursor', handleOnMoveCursor); + console.log('someone connectted'); + const isNotHost = (host, username) => host.username !== username; + const isFirstVisit = (participants, username) => + indexOfUser(participants, username) === -1; + const indexOfUser = (participants, username) => + participants.findIndex( + participant => participant.username === username + ); + + const handleCreateRoom = ({ projectId, user, project }) => { + socket.user = user; + socket.room = projectId; + socket.join(projectId); + + if (rooms[projectId]) { + // 방에 참여하는 경우 + const { host, participants } = rooms[socket.room]; + const { + user: { username } + } = socket; + + // 호스트 혹은 이미 접속한 사람이 재접속했을 때 참가자에 추가되는 것을 방지 + if ( + isNotHost(host, username) && + isFirstVisit(participants, username) + ) { + if (!socket.user) socket.user = userName.pop(); + participants.push(socket.user); + } + + // 본인에게 알리기 + socket.emit('alreadyExistRoom', { host, project }); + } else { + // 방을 생성하는 경우 + rooms[projectId] = { + host: user, + project, + participants: [] + }; + + // 본인에게 알리기 + socket.emit('successCreatedRoom', { project }); + } + + const { participants } = rooms[socket.room]; + + // 해당 방에 있는 사람들에게 알리기 + io.in(socket.room).emit('joinUser', { participants }); + }; + + const handleDisconnect = () => { + if (!rooms[socket.room]) return; + const { host, participants } = rooms[socket.room]; + const { + user: { username } + } = socket; + socket.leave(socket.room); + + if (host.username === username) { + // 호스트가 연결이 끊긴 경우 + rooms[socket.room] = null; + io.sockets.in(socket.room).emit('close'); + } else { + // 게스트가 연결이 끊긴 경우 + participants.splice(indexOfUser(participants, username), 1); + io.in(socket.room).emit('leaveUser', { participants }); + } + }; + + const handleCloseSocket = () => { + // 호스트가 라이브를 중지한 경우 + rooms[socket.room] = null; + io.sockets.in(socket.room).emit('close'); + }; + + const handleOnChange = (filePath, operation) => { + io.in(socket.room).emit('change', socket.id, filePath, operation); + }; + + const handleOnMoveCursor = (filePath, position) => { + socket.broadcast.emit( + 'moveCursor', + socket.user.username, + filePath, + position + ); + }; + + socket.emit('connected'); + socket.on('createRoom', handleCreateRoom); + socket.on('disconnect', handleDisconnect); + socket.on('close', handleCloseSocket); + socket.on('change', handleOnChange); + socket.on('moveCursor', handleOnMoveCursor); }); -io.listen(PORT); \ No newline at end of file +io.listen(PORT); From c1164e428fa3edd7f0db9c610626107cb592e8fb Mon Sep 17 00:00:00 2001 From: Basiltoast Date: Fri, 20 Dec 2019 01:17:26 +0900 Subject: [PATCH 10/10] =?UTF-8?q?chore:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- live-server/app.js | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/live-server/app.js b/live-server/app.js index 8eefaeb0..79f53076 100644 --- a/live-server/app.js +++ b/live-server/app.js @@ -4,14 +4,9 @@ const PORT = 3040; const rooms = {}; io.on('connection', socket => { - console.log('someone connectted'); const isNotHost = (host, username) => host.username !== username; - const isFirstVisit = (participants, username) => - indexOfUser(participants, username) === -1; - const indexOfUser = (participants, username) => - participants.findIndex( - participant => participant.username === username - ); + const isFirstVisit = (participants, username) => indexOfUser(participants, username) === -1; + const indexOfUser = (participants, username) => participants.findIndex(participant => participant.username === username); const handleCreateRoom = ({ projectId, user, project }) => { socket.user = user; @@ -26,13 +21,7 @@ io.on('connection', socket => { } = socket; // 호스트 혹은 이미 접속한 사람이 재접속했을 때 참가자에 추가되는 것을 방지 - if ( - isNotHost(host, username) && - isFirstVisit(participants, username) - ) { - if (!socket.user) socket.user = userName.pop(); - participants.push(socket.user); - } + if (isNotHost(host, username) && isFirstVisit(participants, username)) participants.push(socket.user); // 본인에게 알리기 socket.emit('alreadyExistRoom', { host, project }); @@ -84,12 +73,7 @@ io.on('connection', socket => { }; const handleOnMoveCursor = (filePath, position) => { - socket.broadcast.emit( - 'moveCursor', - socket.user.username, - filePath, - position - ); + socket.broadcast.emit('moveCursor', socket.user.username, filePath, position); }; socket.emit('connected');