Skip to content

Commit

Permalink
add a websocket chat example
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Feb 16, 2024
1 parent 32fcf1a commit 3cf4fa4
Show file tree
Hide file tree
Showing 10 changed files with 1,323 additions and 57 deletions.
1 change: 1 addition & 0 deletions examples/with-websocket-slim/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/public/build
77 changes: 77 additions & 0 deletions examples/with-websocket-slim/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ws, delay } from 'msw'
import { setupWorker } from 'msw/browser'

const service = ws.link('wss://*')

function formatMessage(username: string, message: string) {
return JSON.stringify({ username, message })
}

const worker = setupWorker(
service.on('connection', ({ client }) => {
client.addEventListener('message', async (event) => {
const { username, message } = JSON.parse(event.data)

// First, broadcast the client message to other clients.
service.broadcastExcept(client, formatMessage(username, message))

await delay()

// Then, respond to the message for everyone to see.
service.broadcast(formatMessage('msw-bot', `Welcome, ${username}!`))

setTimeout(() => {
service.broadcast(formatMessage('msw-bot', 'How are you?'))
}, 1500)
})
}),
)

await worker.start()

// App.
const chat = document.getElementById('chat') as HTMLOListElement
const form = document.getElementById('chat-message') as HTMLFormElement

const client = new WebSocket('wss://example.com')
client.onerror = () => console.error('WebSocket client error')

client.addEventListener('open', () => {
form.addEventListener('submit', (event) => {
event.preventDefault()

const data = new FormData(event.target as HTMLFormElement)
const username = data.get('username') as string
const message = data.get('message') as string
form.reset()

renderMessage(username, message)
client.send(formatMessage(username, message))
})
})

client.addEventListener('message', (event) => {
const { username, message } = JSON.parse(event.data)
renderMessage(username, message, 'incoming')
})

function renderMessage(
author: string,
text: string,
type: 'incoming' | 'outgoing' = 'outgoing',
) {
const messageParent = document.createElement('li')

const authorText = document.createElement('strong')
authorText.textContent = author
authorText.classList.add('author')

const message = document.createElement('span')
message.textContent = text
message.classList.add('message', type)

messageParent.appendChild(authorText)
messageParent.appendChild(message)
chat.appendChild(messageParent)
chat.scrollTop = chat.scrollHeight
}
16 changes: 16 additions & 0 deletions examples/with-websocket-slim/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"type": "module",
"name": "with-websocket",
"scripts": {
"start": "tsx ./server.ts"
},
"dependencies": {
"@fastify/static": "^7.0.1",
"fastify": "^4.26.1",
"msw": "^2.2.0"
},
"devDependencies": {
"tsup": "^8.0.2",
"tsx": "^4.7.1"
}
}
20 changes: 20 additions & 0 deletions examples/with-websocket-slim/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE >
<html>
<head>
<title>WebSocket + MSW Example</title>
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<div id="container">
<h1>WebSocket Example</h1>
<ol id="chat"></ol>
<form id="chat-message">
<input type="text" name="username" />
<input type="text" name="message" />
<button type="submit">Send</button>
</form>
</div>

<script type="module" src="/build/index.js"></script>
</body>
</html>
Loading

0 comments on commit 3cf4fa4

Please sign in to comment.