Verified Commit e66d4da1 authored by Aral Balkan's avatar Aral Balkan
Browse files

Improve the WebSocket documentation and examples.

parent e9433921
......@@ -763,6 +763,28 @@ site/
└ index.js
```
Here, for example, is a simple single-room chat app that broadcasts messages to all connected WebSocket clients:
```js
module.exports = (currentClient, request) {
ws.on('message', message => {
this.getWss().clients.forEach(client => {
client.send(message)
})
})
})
```
To test it out, run Site.js and then open up the JavaScript console in a couple of browser windows and enter the following code into them:
```js
const socket = new WebSocket('https://localhost/chat')
socket.onmessage = message => console.log(message.data)
socket.send('Hello!')
```
For a slightly more sophisticated example that doesn’t broadcast a client’s own messages to itself and has selective broadcast (so you can create “rooms”), please see the [Basic Chat example](examples/wss-basic-chat).
#### Advanced routing (routes.js file)
File-based routing should get you pretty far for simple use cases but if you need full flexibility in routing, simply define a _routes.js_ in your _.dynamic_ folder:
......@@ -777,23 +799,18 @@ The _routes.js_ file should export a function that accepts a reference to the Ex
```js
module.exports = app => {
// HTTPS route with a parameter called id.
app.get('/photo/:id', (request, response) {
response.type('html').end(`
<h1>Photo with ID ${id}</h1>
<img src='/photos/${id}'>
`)
// HTTPS route with a parameter called thing.
app.get('/hello/:thing', (request, response) => {
response
.type('html')
.end(`<h1>Hello, ${request.params.thing}!</h1>`)
})
// WebSocket route: push a random photo every 30 seconds.
app.ws('/random-photos', (webSocket, request) {
setInterval(() => {
const photoId = Math.round(Math.random()*100)
webSocket.send(photoId)
}, 30000)
// WebSocket route: echos messages back to the client that sent them.
app.ws('/echo', (client, request) => {
client.on('message', (data) => {
client.send(data)
})
}
```
......
......@@ -8,10 +8,28 @@
// any inner functions inside of your route
// (like the event handler in this example).
//
module.exports = function (webSocket, request) {
webSocket.on('message', message => {
this.getWss('/chat').clients.forEach(client => {
client.send(message)
module.exports = function (currentClient, request) {
// A new client connection has been made.
// Persist the connection path on the client so we can check for it later
// to ensure that we broadcast messages only to clients on the same path.
// This is how you would implement rooms in a chat app.
currentClient.room = request.url.replace('/.websocket', '')
// Handle messages received from this client.
currentClient.on('message', message => {
let count = 0;
this.getWss().clients.forEach((client) => {
// Ensure that messages are only sent to clients connected to this route (/chat).
const notSendingToSelf = client !== currentClient
const theRoomIsCorrect = client.room === '/chat'
const theSocketIsOpen = currentClient.readyState === 1 /* WebSocket.OPEN */
if (notSendingToSelf && theRoomIsCorrect && theSocketIsOpen) {
client.send(message)
count++
}
})
console.log(`/chat message broadcast to ${count} client${count === 1 ? '' : 's'}.`)
})
}
......@@ -15,9 +15,9 @@
<input id='message' type='text' name='message' value=''>
<button id='submitButton' type='submit'>Send</button>
</form>
<h2>Received messages</h2>
<h2>Messages</h2>
<!-- In actual app would use Aria to announce received messages. -->
<ul id='received'></ul>
<ul id='messages'></ul>
<script>
window.addEventListener('load', () => {
......@@ -30,6 +30,10 @@
$('#submitButton').disabled = !formIsValid
}
function displayMessage (message) {
$('#messages').innerHTML += `<li><strong>${message.nickname}: </strong>${message.text}</li>`
}
// Perform initial form validation.
validateForm()
......@@ -47,7 +51,7 @@
// Display received messages.
socket.onmessage = message => {
message = JSON.parse(message.data)
$('#received').innerHTML += `<li><strong>${message.nickname}: </strong>${message.text}</li>`
displayMessage(message)
}
// Carry out form validation.
......@@ -68,8 +72,11 @@
validateForm()
// Send the message
socket.send(JSON.stringify({ nickname, text }))
const message = { nickname, text }
socket.send(JSON.stringify(message))
// Update the local display
displayMessage(message)
})
})
</script>
......
// Basic echo.
module.exports = (webSocket, request) => {
webSocket.on('message', (data) => {
webSocket.send(data)
module.exports = (client, request) => {
client.on('message', (data) => {
client.send(data)
})
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment