Advanced Chat
Here, we have a slightly more complex chat, with both chat and emote messages.
By using type routing, we can listen for each message type separately.
We also track connected users via { list: true } — no custom greeting protocol needed.
In this window, you are .... To chat with yourself, open this page in another tab.
no messages yet...
Connected Users
import { connect } from 'itty-sockets'
type ChatMessage = { type: 'chat', text: string }
type EmoteMessage = { type: 'emote', action: string }
let users = []
const chat = connect('examples:typed-chat', {
announce: true,
echo: true,
list: true,
as: '...',
})
.on('join', ({ uid, alias, users: list }) => {
if (list) users = list
else if (uid) users.push({ uid, alias })
})
.on('leave', ({ uid }) => {
users = users.filter(u => u.uid !== uid)
})
.on<ChatMessage>('chat', ({ alias, text }) => {
// "Kevin: hello!"
})
.on<EmoteMessage>('emote', ({ alias, action }) => {
// "*Kevin waves*"
})
chat.send<ChatMessage>({ type: 'chat', text: 'hello!' })
chat.send<EmoteMessage>({ type: 'emote', action: 'waves' })Alternatively, you can use an event map to type the connection while keeping your downstream code cleaner:
import { connect } from 'itty-sockets'
type ChatMessage = { type: 'chat', text: string }
type EmoteMessage = { type: 'emote', action: string }
type Events = {
chat: ChatMessage
emote: EmoteMessage
}
let users = []
const chat = connect<Events>('examples:typed-chat', {
announce: true,
echo: true,
list: true,
as: '...',
})
.on('join', ({ uid, alias, users: list }) => {
if (list) users = list
else if (uid) users.push({ uid, alias })
})
.on('leave', ({ uid }) => {
users = users.filter(u => u.uid !== uid)
})
.on('chat', ({ alias, text }) => {
// "Kevin: hello!"
})
.on('emote', ({ alias, action }) => {
// "*Kevin waves*"
})
chat.send({ type: 'chat', text: 'hello!' })
chat.send({ type: 'emote', action: 'waves' })