Set up simple chat server
This commit is contained in:
@@ -1,7 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
<script lang="ts">
|
||||
import Game from './components/Game.vue'
|
||||
|
||||
/*
|
||||
Basically just opens the websocket connection to the server,
|
||||
waits for the 'init' message and passes the initial state to the Game
|
||||
component. Once the initial state has been received, no more event are processed.
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
Game
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ws: new WebSocket('ws://localhost:5000/glebby'),
|
||||
model: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const messageListener = (ev: MessageEvent) => {
|
||||
const message = JSON.parse(ev.data)
|
||||
const payload = message.payload
|
||||
|
||||
if (payload.type === 'init') {
|
||||
console.log('Received initial game state:')
|
||||
console.log(payload.state)
|
||||
this.model = payload.state
|
||||
this.ws.removeEventListener('message', messageListener)
|
||||
}
|
||||
}
|
||||
|
||||
this.ws.addEventListener('message', messageListener)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<HelloWorld msg="Vite + Vue" />
|
||||
<Game v-if="model" :ws="ws" :model="model" />
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
interface Player {
|
||||
id: number,
|
||||
name: string
|
||||
}
|
||||
|
||||
interface Model {
|
||||
yourId: number,
|
||||
players: Player[]
|
||||
}
|
||||
|
||||
function getPlayer(model: Model, id: number): Player | undefined {
|
||||
return model.players.find(player => player.id === id)
|
||||
}
|
||||
|
||||
/*
|
||||
Handles all game business. Sends (local) player input to the server for distribution.
|
||||
Receives player input from the server and manages state accordingly.
|
||||
*/
|
||||
export default defineComponent({
|
||||
props: {
|
||||
ws: { type: WebSocket, required: true },
|
||||
model: { type: Object as PropType<Model>, required: true }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chatMessages: [] as string[],
|
||||
|
||||
playerName: '',
|
||||
chatMessage: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.ws.addEventListener('message', (ev) => {
|
||||
const message = JSON.parse(ev.data)
|
||||
const payload = message.payload
|
||||
console.log(`Message from player ${message.from}:`)
|
||||
console.log(payload)
|
||||
|
||||
switch (payload.type) {
|
||||
case 'join':
|
||||
this.model.players.push({
|
||||
id: message.from,
|
||||
name: ''
|
||||
})
|
||||
break
|
||||
case 'leave':
|
||||
this.model.players = this.model.players.filter(player => player.id !== message.from)
|
||||
break
|
||||
case 'chat':
|
||||
this.chatMessages.push(payload.message)
|
||||
break
|
||||
case 'set-name':
|
||||
getPlayer(this.model, message.from)!.name = payload.name
|
||||
break
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
setName() {
|
||||
this.ws.send(JSON.stringify({
|
||||
type: 'set-name',
|
||||
name: this.playerName
|
||||
}))
|
||||
},
|
||||
sendChat() {
|
||||
if (this.chatMessage === '') {
|
||||
return
|
||||
}
|
||||
|
||||
this.ws.send(JSON.stringify({
|
||||
type: 'chat',
|
||||
message: this.chatMessage
|
||||
}))
|
||||
this.chatMessage = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<pre>{{ JSON.stringify(model, null, 2) }}</pre>
|
||||
<h1>I am #{{ model.yourId }}</h1>
|
||||
<form @submit.prevent="setName">
|
||||
<input v-model="playerName" placeholder="enter your name...">
|
||||
<button >set name</button>
|
||||
</form>
|
||||
<form @submit.prevent="sendChat">
|
||||
<input v-model="chatMessage">
|
||||
<button>Post</button>
|
||||
</form>
|
||||
<h2>players</h2>
|
||||
<ul v-if="model">
|
||||
<li v-for="player in model.players" :key="player.id">{{ player.name }}#{{ player.id }}</li>
|
||||
</ul>
|
||||
<h2>chat</h2>
|
||||
<ul v-if="model">
|
||||
<li v-for="message in chatMessages">{{ message }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
@@ -1,15 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{ msg: string }>()
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<div class="card">
|
||||
<button type="button" @click="count++">count is {{ count }}</button>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user