1
0
Fork 0
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:
Sergio Daniel Xalambrí 2017-04-22 07:53:48 -05:00 committed by Tim Neutkens
parent ce0a2f7b13
commit 1bb20b1930
4 changed files with 163 additions and 0 deletions

View 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/)

View 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"
}
}

View 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

View 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')
})
})