mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add socket.io example (#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
This commit is contained in:
parent
ce0a2f7b13
commit
1bb20b1930
25
examples/with-socket.io/README.md
Normal file
25
examples/with-socket.io/README.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
[![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)
|
||||
|
||||
# Socket.io example
|
||||
|
||||
## How to use
|
||||
|
||||
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-socket.io
|
||||
cd with-socket.io
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## The idea behind the example
|
||||
|
||||
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.
|
||||
|
||||
**Example:** [https://next-socket-io.now.sh/](https://next-socket-io.now.sh/)
|
16
examples/with-socket.io/package.json
Normal file
16
examples/with-socket.io/package.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"express": "^4.15.2",
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
"next": "latest",
|
||||
"react": "^15.5.4",
|
||||
"react-dom": "^15.5.4",
|
||||
"socket.io": "^1.7.3",
|
||||
"socket.io-client": "^1.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "node server.js",
|
||||
"build": "next build",
|
||||
"start": "NODE_ENV=production node server.js"
|
||||
}
|
||||
}
|
88
examples/with-socket.io/pages/index.js
Normal file
88
examples/with-socket.io/pages/index.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
import { Component } from 'react'
|
||||
import io from 'socket.io-client'
|
||||
import fetch from 'isomorphic-fetch'
|
||||
|
||||
class HomePage extends Component {
|
||||
// fetch old messages data from the server
|
||||
static async getInitialProps ({ req }) {
|
||||
const response = await fetch('http://localhost:3000/messages')
|
||||
const messages = await response.json()
|
||||
return { messages }
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
messages: []
|
||||
}
|
||||
|
||||
// init state with the prefetched messages
|
||||
state = {
|
||||
field: '',
|
||||
messages: this.props.messages
|
||||
}
|
||||
|
||||
// connect to WS server and listen event
|
||||
componentDidMount () {
|
||||
this.socket = io('http://localhost:3000/')
|
||||
this.socket.on('message', this.handleMessage)
|
||||
}
|
||||
|
||||
// close socket connection
|
||||
componentWillUnmount () {
|
||||
this.socket.off('message', this.handleMessage)
|
||||
this.socket.close()
|
||||
}
|
||||
|
||||
// add messages from server to the state
|
||||
handleMessage = (message) => {
|
||||
this.setState(state => ({ messages: state.messages.concat(message) }))
|
||||
}
|
||||
|
||||
handleChange = event => {
|
||||
this.setState({ field: event.target.value })
|
||||
}
|
||||
|
||||
// send messages to server and add them to the state
|
||||
handleSubmit = event => {
|
||||
event.preventDefault()
|
||||
|
||||
// create message object
|
||||
const message = {
|
||||
id: (new Date()).getTime(),
|
||||
value: this.state.field
|
||||
}
|
||||
|
||||
// send object to WS server
|
||||
this.socket.emit('message', message)
|
||||
|
||||
// add it to state and clean current input value
|
||||
this.setState(state => ({
|
||||
field: '',
|
||||
messages: state.messages.concat(message)
|
||||
}))
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<main>
|
||||
<div>
|
||||
<ul>
|
||||
{this.state.messages.map(message =>
|
||||
<li key={message.id}>{message.value}</li>
|
||||
)}
|
||||
</ul>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<input
|
||||
onChange={this.handleChange}
|
||||
type='text'
|
||||
placeholder='Hello world!'
|
||||
value={this.state.field}
|
||||
/>
|
||||
<button>Send</button>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default HomePage
|
34
examples/with-socket.io/server.js
Normal file
34
examples/with-socket.io/server.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
const app = require('express')()
|
||||
const server = require('http').Server(app)
|
||||
const io = require('socket.io')(server)
|
||||
const next = require('next')
|
||||
|
||||
const dev = process.env.NODE_ENV !== 'production'
|
||||
const nextApp = next({ dev })
|
||||
const nextHandler = nextApp.getRequestHandler()
|
||||
|
||||
// fake DB
|
||||
const messages = []
|
||||
|
||||
// socket.io server
|
||||
io.on('connection', socket => {
|
||||
socket.on('message', (data) => {
|
||||
messages.push(data)
|
||||
socket.broadcast.emit('message', data)
|
||||
})
|
||||
})
|
||||
|
||||
nextApp.prepare().then(() => {
|
||||
app.get('/messages', (req, res) => {
|
||||
res.json(messages)
|
||||
})
|
||||
|
||||
app.get('*', (req, res) => {
|
||||
return nextHandler(req, res)
|
||||
})
|
||||
|
||||
server.listen(3000, (err) => {
|
||||
if (err) throw err
|
||||
console.log('> Ready on http://localhost:3000')
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue