-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
867 additions
and
418 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,125 @@ | ||
<script setup lang="ts"> | ||
const logs = ref<string[]>([]) | ||
const log = (...args: any[]) => { | ||
console.log("[ws]", ...args); | ||
logs.value.push(args.join(" ")); | ||
let ws: WebSocket | undefined; | ||
const store = reactive({ | ||
message: "", | ||
messages: [] as { user: string, text: string, date: string }[], | ||
}); | ||
const log = (user: string, ...args: string[]) => { | ||
console.log("[ws]", user, ...args); | ||
store.messages.push({ | ||
text: args.join(" "), | ||
user: user, | ||
date: new Date().toLocaleString(), | ||
}); | ||
}; | ||
let ws: WebSocket | undefined | ||
const connect = async () => { | ||
const isSecure = location.protocol === "https:"; | ||
const url = (isSecure ? "wss:https://" : "ws:https://") + location.host + "/_ws"; | ||
if (ws) { | ||
log("Closing..."); | ||
log("ws", "Closing previous connection before reconnecting..."); | ||
ws.close(); | ||
clear(); | ||
} | ||
log("Connecting to", url, "..."); | ||
log("ws", "Connecting to", url, "..."); | ||
ws = new WebSocket(url); | ||
ws.addEventListener("close", () => { | ||
log("Connection closed"); | ||
}); | ||
ws.addEventListener("error", (event) => { | ||
log("Error:", event); | ||
}); | ||
ws.addEventListener("message", (event) => { | ||
log("Message from server:", event.data); | ||
const { user = "system", message = "" } = event.data.startsWith("{") | ||
? JSON.parse(event.data) | ||
: { message: event.data }; | ||
log( | ||
user, | ||
typeof message === "string" ? message : JSON.stringify(message), | ||
); | ||
}); | ||
log("Waiting for connection..."); | ||
await new Promise((resolve) => ws!.addEventListener("open", resolve)); | ||
log("ws", "Connected!"); | ||
}; | ||
const clearLogs = () => { | ||
logs.value = [] | ||
const clear = () => { | ||
store.messages.splice(0, store.messages.length); | ||
log("system", "previous messages cleared"); | ||
}; | ||
const sendPing = () => { | ||
log("Sending ping..."); | ||
ws?.send("ping"); | ||
const send = () => { | ||
console.log("sending message..."); | ||
if (store.message) { | ||
ws!.send(store.message); | ||
} | ||
store.message = ""; | ||
}; | ||
const message = ref<string>("ping") | ||
const sendMessage = () => { | ||
ws?.send(message.value); | ||
const ping = () => { | ||
log("ws", "Sending ping"); | ||
ws!.send("ping"); | ||
}; | ||
onMounted(async () => { | ||
await connect(); | ||
sendPing(); | ||
const rand = Math.random() | ||
onMounted(() => { | ||
connect(); | ||
}); | ||
useServerHead({ | ||
title: "Nuxt Chat", | ||
}) | ||
</script> | ||
|
||
<template> | ||
<div class="ms-m-5" data-theme="dark"> | ||
<h3>Nuxt ❤️ WS</h3> | ||
|
||
<div class="ms-btn-group"> | ||
<button @click="sendPing">Send Ping</button> | ||
<button @click="connect">Reconnect</button> | ||
<button @click="clearLogs">Clear</button> | ||
</div> | ||
|
||
<div class="ms-form-group ms-mt-2"> | ||
<div class="row"> | ||
<div class="col-sm-6"> | ||
<input type="email" class="ms-secondary ms-small" id="message" placeholder="Message..." v-model="message" | ||
@keydown.enter="sendMessage" /> | ||
<div class="h-screen flex flex-col justify-between" style="background-color: #1a1a1a"> | ||
<main> | ||
<div class="flex flex-col text-white" style="position: fixed; right: 0;"> | ||
<a href="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/pi0/nuxt-websocket"> | ||
view source on GitHub | ||
</a> | ||
</div> | ||
|
||
|
||
<!-- Messages --> | ||
<div id="messages" class="flex-grow flex flex-col justify-end px-4 py-8"> | ||
<div class="flex items-center mb-4" v-for="message in store.messages"> | ||
<div class="flex flex-col"> | ||
<p class="text-gray-500 mb-1 text-xs ml-10">{{ message.user }}</p> | ||
<div class="flex items-center"> | ||
<img | ||
:src="'https://www.gravatar.com/avatar/' + encodeURIComponent(message.user + rand) + '?s=512&d=monsterid'" | ||
alt="Avatar" class="w-8 h-8 rounded-full" /> | ||
<div class="ml-2 bg-gray-800 rounded-lg p-2"> | ||
<p class="text-white">{{ message.text }}</p> | ||
</div> | ||
</div> | ||
<p class="text-gray-500 mt-1 text-xs ml-10">{{ message.date }}</p> | ||
</div> | ||
</div> | ||
<div class="col-sm-1"> | ||
<button class="ms-btn ms-secondary ms-small" @click="sendMessage"> | ||
</div> | ||
|
||
<!-- Chatbox --> | ||
<div class="bg-gray-800 px-4 py-2 flex items-center justify-between fixed bottom-0 w-full"> | ||
<div class="w-full min-w-6"> | ||
<input type="text" placeholder="Type your message..." | ||
class="w-full rounded-l-lg px-4 py-2 bg-gray-700 text-white focus:outline-none focus:ring focus:border-blue-300" | ||
@keydown.enter="send" v-model="store.message" /> | ||
</div> | ||
<div class="flex"> | ||
<button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4" @click="send"> | ||
Send | ||
</button> | ||
<button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4" @click="ping"> | ||
Ping | ||
</button> | ||
<button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4" @click="connect"> | ||
Reconnect | ||
</button> | ||
<button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-r-lg" @click="clear"> | ||
Clear | ||
</button> | ||
</div> | ||
</div> | ||
<br /> | ||
</div> | ||
<pre id="logs"> | ||
<div v-for="log in logs" :key="log">{{ log }}</div> | ||
</pre> | ||
<hr> | ||
Source code: <a href="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/pi0/nuxt-websocket">https://github.com/pi0/nuxt-websocket</a> | ||
</main> | ||
</div> | ||
</template> | ||
|
||
<style> | ||
@import url('https://cdn.jsdelivr.net/npm/[email protected]/dist/css/minstyle.io.min.css'); | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,5 +4,7 @@ export default defineNuxtConfig({ | |
experimental: { | ||
websocket: true | ||
} | ||
} | ||
}) | ||
}, | ||
|
||
modules: ["@nuxtjs/tailwindcss"] | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.