{"id":1227,"date":"2020-08-13T19:16:14","date_gmt":"2020-08-13T10:16:14","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=1227"},"modified":"2020-08-15T18:50:11","modified_gmt":"2020-08-15T09:50:11","slug":"socket-io-%eb%a5%bc-%ec%9d%b4%ec%9a%a9%ed%95%9c-%ec%b1%84%ed%8c%85%ec%84%9c%eb%b2%84-%ea%b5%ac%ec%b6%95%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=1227","title":{"rendered":"Socket.io \ub97c \uc774\uc6a9\ud55c \ucc44\ud305\uc11c\ubc84 \uad6c\ucd95\ud558\uae30"},"content":{"rendered":"<h1>Socket.io \ub97c \uc774\uc6a9\ud55c \ucc44\ud305\uc11c\ubc84 \uad6c\ucd95\ud558\uae30<\/h1>\n<h2>Socket.io \uc124\uce58\ud558\uae30<\/h2>\n<p><code>Local<\/code> \uacc4\uc815\uc5d0 \uc124\uce58\ud574\uc57c \uc815\uc0c1\uc801\uc73c\ub85c \uc791\ub3d9\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc5ec\ub7ec \uc778\uc2a4\ud134\uc2a4\uac04\uc5d0 \ub370\uc774\ud0c0\ub97c \uacf5\uc720\ud558\uae30 \uc704\ud574 Redis \uc11c\ubc84\ub97c \uc124\uce58\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-bash\">sudo apt-get install redis-server<\/code><\/pre>\n<pre><code class=\"language-bash\">npm install node-gyp\nnpm install socket.io\nnpm install --save-optional bufferutil utf-8-validate\nnpm install express\nnpm install socket.io-redis<\/code><\/pre>\n<h2>\uc11c\ubc84 \uc0dd\uc131<\/h2>\n<h3>server.js<\/h3>\n<pre><code class=\"language-bash\">mkdir chat\nvi chat\/server.js<\/code><\/pre>\n<pre><code class=\"language-javascript\">var express = require(&#039;express&#039;);\nvar app = express();\nvar redisAdapter = require(&#039;socket.io-redis&#039;);\nvar server = require(&#039;http&#039;).Server(app);\nvar io = require(&#039;socket.io&#039;)(server);\nvar redis = require(&#039;redis&#039;);\n\/\/var Promise = require(&#039;promise&#039;);\nconst path = require(&#039;path&#039;);\n\nvar favicon = require(&#039;serve-favicon&#039;);\napp.use(favicon(path.join(__dirname, &#039;public\/images&#039;, &#039;favicon.ico&#039;)));\n\nio.eio.pingTimeout = 60*60*1000; \/\/ 60 minutes\nio.eio.pingInterval = 5*1000;  \/\/ 5 seconds\n\nserver.listen(3000, () =&gt; {\n    console.log(&#039;server on!&#039;);\n});\n\napp.get(&#039;\/&#039;, (req, res) =&gt; {\n    res.sendFile(__dirname + &#039;\/client.html&#039;);\n});\n\nconst namespace1 = io.of(&#039;\/namespace1&#039;);\n\n\/\/ \ub2e4\uc911 \uc778\uc2a4\ud134\uc2a4\uac04 \ub370\uc774\ud0c0 \uacf5\uc720\nio.adapter(redisAdapter({ host: &#039;localhost&#039;, port: 6379 }));\n\n\/\/ redis \ud074\ub77c\uc774\uc5b8\ud2b8 \uc0dd\uc131\nconst REDIS_PREFIX = &#039;CHAT_USER_&#039;;\nconst client = redis.createClient();\n\nclient.on(&#039;error&#039;, function (err) {\n    console.log(&#039;Error &#039; + err);\n});\n\nnamespace1.on(&#039;connection&#039;, (socket) =&gt;  {\n    socket.nickname = socket.id;\n    socket.emit(&#039;new&#039;,{ nickname : socket.nickname });\n    console.log(&#039;user connected : &#039;, socket.nickname);\n\n    client.hmset(\n        REDIS_PREFIX + socket.id,\n        &#039;nickname&#039;, socket.nickname\n    );\n\n    \/\/ \ucc44\ud305\ubc29 \uc811\uc18d\n    socket.join(&#039;my room&#039;);\n\n    \/\/ \uc811\uc18d \uc885\ub8cc\n    socket.on(&#039;disconnect&#039;, function(){\n        console.log(&#039;user disconnected: &#039;, socket.id);\n        client.hdel(\n            REDIS_PREFIX + socket.id,\n            &#039;nickname&#039;\n        );\n    });\n\n    \/\/ \uc11c\ubc84 \uba54\uc2dc\uc9c0 \uc218\uc2e0\n    socket.on(&#039;send message&#039;, function(name,text){\n        var msg = &#039;send message &#039; + name + &#039; : &#039; + text;\n        namespace1.to(&#039;my room&#039;).emit(&#039;receive message&#039;, msg);\n    });\n\n    \/\/ \ub300\ud654\ubc29 \uba54\uc2dc\uc9c0 \uc218\uc2e0\n    socket.on(&#039;chat message&#039;, function(name,text){\n        var msg = &#039;chat message &#039; + name + &#039; : &#039; + text;\n        namespace1.to(&#039;my room&#039;).emit(&#039;chat message&#039;, msg);\n    });\n\n    function saveNickname(socketId, nickname) {\n        return new Promise(function(resolved, rejected) {\n            client.hmset(\n                REDIS_PREFIX + socketId,\n                &#039;nickname&#039;, nickname\n            );\n            return resolved(nickname);\n        });\n    };\n\n    function sendToUser(nickname) {\n        return new Promise(function(resolved, rejected) {\n            sendTo(&#039;aaa&#039;, &#039;new nickname : &#039; + nickname);\n            return resolved(&#039;ok&#039;);\n        });\n    };\n\n    \/\/ \ub2c9\ub124\uc784 \ubcc0\uacbd\n    socket.on(&#039;changename&#039;, function(data) {\n        socket.nickname = data.nickname;\n\n        (async() =&gt; {\n            const nickname = await saveNickname(socket.id, socket.nickname);\n            await sendToUser(nickname);\n        })();\n    });\n\n    function sendTo(nickname, msg) {\n        var socketId, clientId, i;\n\n        io.of(&#039;\/namespace1&#039;).adapter.clients([&#039;my room&#039;], (err, clients) =&gt; {\n            if (err) {\n                console.log(err);\n                return;\n            }\n            for (i = 0; i &lt; clients.length; i++) {\n                socketId = clients[i];\n\n                \/\/ \ud074\ub85c\uc800 \uc774\uc6a9\n                (function(socketId) {\n                    client.hgetall(REDIS_PREFIX + socketId, (err, _socket) =&gt; {\n                        if (_socket.hasOwnProperty(&#039;nickname&#039;) &amp;&amp; _socket.nickname == nickname) {\n                            namespace1.to(socketId).emit(&#039;send message to&#039;, { msg: msg });\n                        }\n                    });\n                })(socketId);\n            }\n        });\n    }\n});\n<\/code><\/pre>\n<h3>client.html<\/h3>\n<pre><code class=\"language-bash\">vi chat\/client.html<\/code><\/pre>\n<pre><code class=\"language-html\">&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n  &lt;head&gt;\n    &lt;meta charset=&quot;utf-8&quot;&gt;\n    &lt;title&gt;Chat&lt;\/title&gt;\n    &lt;style&gt;\n      .chat_log{ width: 95%; height: 200px; }\n      .name{ width: 10%; }\n      .message{ width: 70%; }\n      .chat{ width: 10%; }\n    &lt;\/style&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;div&gt;\n      &lt;textarea id=&quot;chatLog&quot; class=&quot;chat_log&quot; readonly&gt;&lt;\/textarea&gt;\n    &lt;\/div&gt;\n    &lt;form id=&quot;chat&quot;&gt;\n      &lt;input id=&quot;nickname&quot; class=&quot;name&quot; type=&quot;text&quot; \/&gt;\n      &lt;input id=&quot;changename&quot; type=&quot;button&quot; class=&quot;chat&quot; value=&quot;changename&quot;\/&gt;&lt;br \/&gt;\n      &lt;input id=&quot;message&quot; class=&quot;message&quot; type=&quot;text&quot; autocomplete=&quot;off&quot; \/&gt;\n      &lt;input type=&quot;submit&quot; class=&quot;chat&quot; value=&quot;chat&quot;\/&gt;\n    &lt;\/form&gt;\n    &lt;script src=&quot;\/socket.io\/socket.io.js&quot;&gt;&lt;\/script&gt;\n    &lt;script src=&quot;http:\/\/code.jquery.com\/jquery-1.11.1.js&quot;&gt;&lt;\/script&gt;\n    &lt;script type=&quot;text\/javascript&quot;&gt;\n    \/\/ \uc811\uc18d\n    var socket = io(&#039;\/namespace1&#039;, {transports: [&#039;websocket&#039;]});\n\n    \/\/ \uba54\uc2dc\uc9c0 \uc804\uc1a1\n    $(&#039;#chat&#039;).on(&#039;submit&#039;, function(e){\n        \/\/ send message : \uc11c\ubc84 \uba54\uc2dc\uc9c0 \uc804\uc1a1\n        \/\/ chat message : \ub300\ud654\ubc29 \uba54\uc2dc\uc9c0 \uc804\uc1a1\n        \/\/ socket.emit(&#039;send message&#039;, $(&#039;#nickname&#039;).val(), $(&#039;#message&#039;).val());\n        socket.emit(&#039;chat message&#039;, $(&#039;#nickname&#039;).val(), $(&#039;#message&#039;).val());\n        $(&#039;#message&#039;).val(&quot;&quot;);\n        $(&quot;#message&quot;).focus();\n        e.preventDefault();\n    });\n\n    \/\/ \uc11c\ubc84 \uba54\uc2dc\uc9c0 \uc218\uc2e0\n    socket.on(&#039;receive message&#039;, function(msg){\n        $(&#039;#chatLog&#039;).append(msg+&#039;\\n&#039;);\n        $(&#039;#chatLog&#039;).scrollTop($(&#039;#chatLog&#039;)[0].scrollHeight);\n    });\n\n    \/\/ \ub300\ud654\ubc29 \uba54\uc2dc\uc9c0 \uc218\uc2e0\n    socket.on(&#039;chat message&#039;, function(msg){\n        $(&#039;#chatLog&#039;).append(msg+&#039;\\n&#039;);\n        $(&#039;#chatLog&#039;).scrollTop($(&#039;#chatLog&#039;)[0].scrollHeight);\n    });\n\n    \/\/ \uc9c0\uc815 \uba54\uc2dc\uc9c0 \uc218\uc2e0\n    socket.on(&#039;send message to&#039;,function(data){\n        console.log(data.msg);\n    });\n\n    \/\/ \ub2c9\ub124\uc784 \uc218\uc2e0\n    socket.on(&#039;new&#039;,function(data){\n        $(&#039;#nickname&#039;).val(data.nickname);\n    });\n\n    \/\/ \ub2c9\ub124\uc784 \ubcc0\uacbd\n    $(&#039;#changename&#039;).on(&#039;click&#039;, function(e){\n        socket.emit(&#039;changename&#039;, { nickname : $(&#039;#nickname&#039;).val() });\n    });\n    &lt;\/script&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<h3>\uc11c\ubc84 \uc2e4\ud589<\/h3>\n<pre><code class=\"language-bash\">cd chat\nvi ecosystem.config.js<\/code><\/pre>\n<pre><code class=\"language-javascript\">module.exports = {\n  apps : [{\n    name       : &#039;chat-server&#039;,\n    script     : &#039;server.js&#039;,\n    watch      : &#039;.&#039;,\n    instances  : 4\n  }]};<\/code><\/pre>\n<pre><code class=\"language-bash\">pm2 start ecosystem.config.js\npm2 log\npm2 list\npm2 save<\/code><\/pre>\n<p>\ube0c\ub77c\uc6b0\uc800\ub85c \uc811\uc18d\ud558\uba74 \uc815\uc0c1\uc801\uc73c\ub85c \uc11c\ubc84\uac00 \uc2e4\ud589\ub418\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p><a href=\"http:\/\/XXX.XXX.XXX.102:3000\/\">http:\/\/XXX.XXX.XXX.102:3000\/<\/a><\/p>\n<p>\ub450\uac1c \uc774\uc0c1\uc758 \ube0c\ub77c\uc6b0\uc800\ub97c \uc5f4\uc5b4 \ucc44\ud305\uc774 \uacf5\uc720\ub418\ub294 \uac83\uc744 \ud655\uc778 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Socket.io \ub97c \uc774\uc6a9\ud55c \ucc44\ud305\uc11c\ubc84 \uad6c\ucd95\ud558\uae30 Socket.io \uc124\uce58\ud558\uae30 Local \uacc4\uc815\uc5d0 \uc124\uce58\ud574\uc57c \uc815\uc0c1\uc801\uc73c\ub85c \uc791\ub3d9\ud569\ub2c8\ub2e4. \uc5ec\ub7ec \uc778\uc2a4\ud134\uc2a4\uac04\uc5d0 \ub370\uc774\ud0c0\ub97c \uacf5\uc720\ud558\uae30 \uc704\ud574 Redis \uc11c\ubc84\ub97c \uc124\uce58\ud569\ub2c8\ub2e4. sudo apt-get install redis-server npm install node-gyp npm install socket.io npm install &#8211;save-optional bufferutil utf-8-validate npm install express npm install socket.io-redis \uc11c\ubc84 \uc0dd\uc131 server.js mkdir chat vi chat\/server.js var express = require(&#039;express&#039;); var app =\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=1227\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-1227","post","type-post","status-publish","format-standard","hentry","category-node-js"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1227","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1227"}],"version-history":[{"count":21,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1227\/revisions"}],"predecessor-version":[{"id":1257,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1227\/revisions\/1257"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1227"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1227"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1227"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}