diff --git a/api.js b/api.js new file mode 100644 index 0000000..a001add --- /dev/null +++ b/api.js @@ -0,0 +1,37 @@ +const ws = require('ws') + +//WS server +const wss = new ws.Server({ + port: 8090, + perMessageDeflate: { + zlibDeflateOptions: { + chunkSize: 1024, + memLevel: 7, + level: 3 + }, + zlibInflateOptions: { + chunkSize: 10 * 1024 + }, + clientNoContextTakeover: true, + serverNoContextTakeover: true, + serverMaxWindowBits: 10, + concurrencyLimit: 10, + threshold: 1024 + } +}); + +//WS handler +wss.on('connection', (ws, req) => { + console.log(`${req.socket.remoteAddress} connected`) + ws.on('message', msgJSON => { + let msg = JSON.parse(msgJSON) + console.log(`${req.socket.remoteAddress} => ${msgJSON}`) + if (msg.type === 'message') wss.clients.forEach(client => client.send(msgJSON)) + }) + let msg = { + type: "info", + time: Date.now(), + content: "connected" + } + ws.send(JSON.stringify(msg)) +}) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index dec6c9e..5a76166 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1744,16 +1744,6 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "cacache": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", @@ -1780,34 +1770,6 @@ "unique-filename": "^1.1.1" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, "find-cache-dir": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", @@ -1829,25 +1791,6 @@ "path-exists": "^4.0.0" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -1912,16 +1855,6 @@ "minipass": "^3.1.1" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -1938,18 +1871,6 @@ "terser": "^4.6.12", "webpack-sources": "^1.4.3" } - }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.0.0-beta.9", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.9.tgz", - "integrity": "sha512-mu9pg6554GbXDSO8LlxkQM6qUJzUkb/A0FJc9LgRqnU9MCnhzEXwCt1Zx5NObvFpzs2mH2dH/uUCDwL8Qaz9sA==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - } } } }, @@ -11019,6 +10940,93 @@ } } }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.0.0-beta.9", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.9.tgz", + "integrity": "sha512-mu9pg6554GbXDSO8LlxkQM6qUJzUkb/A0FJc9LgRqnU9MCnhzEXwCt1Zx5NObvFpzs2mH2dH/uUCDwL8Qaz9sA==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "vue-router": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.9.tgz", + "integrity": "sha512-CGAKWN44RqXW06oC+u4mPgHLQQi2t6vLD/JbGRDAXm0YpMv0bgpKuU5bBd7AvMgfTz9kXVRIWKHqRwGEb8xFkA==", + "dev": true + }, "vue-style-loader": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", @@ -11268,6 +11276,15 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } } } }, @@ -11579,6 +11596,15 @@ } } }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", @@ -11744,13 +11770,9 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index b899c30..fa2b040 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ }, "dependencies": { "core-js": "^3.6.5", - "vue": "^2.6.11" + "vue": "^2.6.11", + "ws": "^7.3.1" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.0", @@ -18,6 +19,7 @@ "babel-eslint": "^10.1.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", + "vue-router": "^3.4.9", "vue-template-compiler": "^2.6.11" }, "eslintConfig": { diff --git a/public/sym/ic_close_white_24px.svg b/public/sym/ic_close_white_24px.svg new file mode 100755 index 0000000..5704800 --- /dev/null +++ b/public/sym/ic_close_white_24px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/sym/ic_send_white_24px.svg b/public/sym/ic_send_white_24px.svg similarity index 100% rename from src/sym/ic_send_white_24px.svg rename to public/sym/ic_send_white_24px.svg diff --git a/src/App.vue b/src/App.vue index b9128dc..91a86da 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,65 +1,19 @@ @@ -87,16 +41,6 @@ body{ background-color: #313131; box-shadow: 3px 3px 10px #111; } -.messages{ - position: absolute; - margin: 0; - left: 0; - top: 0; - height: calc(100% - 4rem); - width: 100%; - overflow-y: auto; -} - @media (max-width: 55rem){ .content{ width: calc(100%); diff --git a/src/components/error.vue b/src/components/error.vue new file mode 100644 index 0000000..1511f62 --- /dev/null +++ b/src/components/error.vue @@ -0,0 +1,68 @@ + + + + + \ No newline at end of file diff --git a/src/components/icon.vue b/src/components/icon.vue index 18bd6de..8b8fac1 100644 --- a/src/components/icon.vue +++ b/src/components/icon.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/main.js b/src/main.js index 63eb05f..a49b5c3 100644 --- a/src/main.js +++ b/src/main.js @@ -1,8 +1,107 @@ import Vue from 'vue' +import VueRouter from 'vue-router' import App from './App.vue' +import login from './views/login.vue' +import chat from './views/chat.vue' Vue.config.productionTip = false +Vue.use(VueRouter) + +const router = new VueRouter({ + routes: [ + { + path: '/', + name: 'home', + component: login + }, + { + path: '/login', + name: 'login', + component: login + }, + { + path: '/chat', + name: 'chat', + component: chat + } + ] +}) new Vue({ - render: h => h(App), + el: '#app', + router, + template: '', + components: {App} }).$mount('#app') + +export default { + mounted() { + sendMessage() + }, + methods: { + sendMessage(message){ + let msg = { + type: "message", + time: Date.now(), + content: { + message: message + } + } + socket.send(JSON.stringify(msg)) + }, + sendWebSocket(msg){ + socket.send(JSON.stringify(msg)) + } + } +} + +const wsurl = 'ws://127.0.0.1:8090' +const socket = new WebSocket(wsurl) + +function element(id){ return document.getElementById(id)} + +socket.onopen = () => { + let msg = { + type: "info", + time: Date.now(), + content: "new session" + } + socket.send(JSON.stringify(msg)) +} +socket.onerror = (error) => { + console.log(`WebSocket error: ${error}`) +} +socket.onclose = () => show_error('session ended (refresh)') +socket.onmessage = (e) => { + console.log(`data received => ${e.data}`) + let msg = JSON.parse(e.data) + if (msg.type === 'error') show_error(msg.content) + else if (msg.type === 'message'){ + //just for now, ik it's dirty + element('messages').innerHTML += + `
+
+ ${msg.content.text} +
+
`; + } +} + +function show_error(msg) { + let error_style = element('errorBox').style + element('errorMessage').innerText = msg + error_style.display = "block" + error_style.animation = "slide-from-left alternate 0.2s" + setTimeout(() => {error_style.animation = ""}, 200) +} + +function sendMessage(message){ + let msg = { + type: "message", + time: Date.now(), + content: { + message: message + } + } + socket.send(JSON.stringify(msg)) +} \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..e69de29 diff --git a/src/views/chat.vue b/src/views/chat.vue new file mode 100644 index 0000000..b4a4ed1 --- /dev/null +++ b/src/views/chat.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..5d00cde --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,28 @@ + + + + + \ No newline at end of file diff --git a/vue.config.js b/vue.config.js new file mode 100644 index 0000000..1c5377c --- /dev/null +++ b/vue.config.js @@ -0,0 +1,3 @@ +module.exports = { + runtimeCompiler: true +} \ No newline at end of file