Skip to content

Commit 1bb20b1

Browse files
sergiodxatimneutkens
authored andcommitted
Add socket.io example (vercel#1766)
* Add socket.io example * [update] stop handling events before unmount * [update] add deploy to now button * Fix linting problems * Fix last missing linting problem
1 parent ce0a2f7 commit 1bb20b1

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed

examples/with-socket.io/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-socket.io)
2+
3+
# Socket.io example
4+
5+
## How to use
6+
7+
Download the example [or clone the repo](https://github.com/zeit/next.js):
8+
9+
```bash
10+
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-socket.io
11+
cd with-socket.io
12+
```
13+
14+
Install it and run:
15+
16+
```bash
17+
npm install
18+
npm run dev
19+
```
20+
21+
## The idea behind the example
22+
23+
This example show how to use [socket.io](https://socket.io/) inside a Next.js application. It uses `getInitialProps` to fetch the old messages from a HTTP endpoint as if it was a Rest API. The example combine the WebSocket server with the Next server, in a production application you should split them as different services.
24+
25+
**Example:** [https://next-socket-io.now.sh/](https://next-socket-io.now.sh/)

examples/with-socket.io/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"dependencies": {
3+
"express": "^4.15.2",
4+
"isomorphic-fetch": "^2.2.1",
5+
"next": "latest",
6+
"react": "^15.5.4",
7+
"react-dom": "^15.5.4",
8+
"socket.io": "^1.7.3",
9+
"socket.io-client": "^1.7.3"
10+
},
11+
"scripts": {
12+
"dev": "node server.js",
13+
"build": "next build",
14+
"start": "NODE_ENV=production node server.js"
15+
}
16+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Component } from 'react'
2+
import io from 'socket.io-client'
3+
import fetch from 'isomorphic-fetch'
4+
5+
class HomePage extends Component {
6+
// fetch old messages data from the server
7+
static async getInitialProps ({ req }) {
8+
const response = await fetch('http://localhost:3000/messages')
9+
const messages = await response.json()
10+
return { messages }
11+
}
12+
13+
static defaultProps = {
14+
messages: []
15+
}
16+
17+
// init state with the prefetched messages
18+
state = {
19+
field: '',
20+
messages: this.props.messages
21+
}
22+
23+
// connect to WS server and listen event
24+
componentDidMount () {
25+
this.socket = io('http://localhost:3000/')
26+
this.socket.on('message', this.handleMessage)
27+
}
28+
29+
// close socket connection
30+
componentWillUnmount () {
31+
this.socket.off('message', this.handleMessage)
32+
this.socket.close()
33+
}
34+
35+
// add messages from server to the state
36+
handleMessage = (message) => {
37+
this.setState(state => ({ messages: state.messages.concat(message) }))
38+
}
39+
40+
handleChange = event => {
41+
this.setState({ field: event.target.value })
42+
}
43+
44+
// send messages to server and add them to the state
45+
handleSubmit = event => {
46+
event.preventDefault()
47+
48+
// create message object
49+
const message = {
50+
id: (new Date()).getTime(),
51+
value: this.state.field
52+
}
53+
54+
// send object to WS server
55+
this.socket.emit('message', message)
56+
57+
// add it to state and clean current input value
58+
this.setState(state => ({
59+
field: '',
60+
messages: state.messages.concat(message)
61+
}))
62+
}
63+
64+
render () {
65+
return (
66+
<main>
67+
<div>
68+
<ul>
69+
{this.state.messages.map(message =>
70+
<li key={message.id}>{message.value}</li>
71+
)}
72+
</ul>
73+
<form onSubmit={this.handleSubmit}>
74+
<input
75+
onChange={this.handleChange}
76+
type='text'
77+
placeholder='Hello world!'
78+
value={this.state.field}
79+
/>
80+
<button>Send</button>
81+
</form>
82+
</div>
83+
</main>
84+
)
85+
}
86+
}
87+
88+
export default HomePage

examples/with-socket.io/server.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const app = require('express')()
2+
const server = require('http').Server(app)
3+
const io = require('socket.io')(server)
4+
const next = require('next')
5+
6+
const dev = process.env.NODE_ENV !== 'production'
7+
const nextApp = next({ dev })
8+
const nextHandler = nextApp.getRequestHandler()
9+
10+
// fake DB
11+
const messages = []
12+
13+
// socket.io server
14+
io.on('connection', socket => {
15+
socket.on('message', (data) => {
16+
messages.push(data)
17+
socket.broadcast.emit('message', data)
18+
})
19+
})
20+
21+
nextApp.prepare().then(() => {
22+
app.get('/messages', (req, res) => {
23+
res.json(messages)
24+
})
25+
26+
app.get('*', (req, res) => {
27+
return nextHandler(req, res)
28+
})
29+
30+
server.listen(3000, (err) => {
31+
if (err) throw err
32+
console.log('> Ready on http://localhost:3000')
33+
})
34+
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy