This is a small haskell program implementing a udp broadcast chat client.
- You can run with..
bcast username
to broadcast on a LAN, or..bcast username listenHost listenPort [destHost destPort ...]
to specify alternate destination addresses.
- Type words, use the left, right, home, end keys to move the cursor.
- Press enter to send.
- Press escape to quit. (
/quit
isn't a command, just for show)
- A
vty
is used to get events from the user and display the UI. - A
TVar
appState
is the content which is displayed in the UI. - A
TChan
netOutbox
is the outgoing event buffer. - A
TChan
netInbox
is the incoming event buffer. - A socket is used to send and receive on the network.
- frontendInput: Block until a
vty
event, apply the event toappState
, optionally emit tonetOutbox
.- Not all
vty
events require a network event. When typing into the buffer, events are handled by applying toappState
directly so the UI can update. When you press the "Enter" key, the buffer is cleared and a network event is emitted.
- Not all
- fontendDisplay: Render
appState
tovty
and then block untilappState
changes. - backendSend: Block until a
netOutbox
event, broadcast it to the network (and also copy it over tonetInbox
).- We copy events directly from the outbox to the inbox because the user shouldn't have to wait for the network to get feedback from the UI. If you're implementing a message-delivery protocol, then you might be required to order outgoing messages, and so this behavior might be incorrect.
- backendReceive: Block until the network receives a packet, deserialize it
and emit to
netInbox
. - protocolReordering: Block until a
netInbox
event and apply it toappState
.- This is kind of a silly thread that doesn't do very much but shuffle things between references. It's somewhat of a placeholder for if you were implementing a message-delivery protocol. Much of the time you'd need to reorder and delay received messages before delivering them to the application. This thread might be where that code would go?
vty
provides the UI.network
provides the sockets.async
provides threads.stm
provides mutable references which can be accessed atomically.