萌新向使用指南
create-react-app
npm start
暂时不知道配置在哪。默认端口为3000
,被占用时会询问是否更改端口。且默认为热启动,组件和CSS的更改都会自动更新。
对于stylus
,stylus-loader
可以使.styl
文件被直接使用,未尝试过。也可以引入CSS
文件,然后使用stylus -w style.styl -o style.css
来自动编译成CSS
。
npm run build
生成的html
文件不能直接打开,需要配置服务器,并将静态目录设置为生成的build
文件夹。若要直接打开查看,只需将html
文件中所有资源引用的地址前加上.
,变成./xxx
即可。(可通过配置package.json
直接生成这样的路径,但并不推荐,详见这里)
socket.io
服务端
可与express
一起使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const app = require('express')()
const server = require('http').createServer(app)
const io = require('socket.io')(server)
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html')
})
io.on('connection', function(socket) {
console.log('a user connected')
})
// 只能使用server进行监听
server.listen(3000, function() {
console.log('listening on *:3000')
})
注意:此时server.listen()
中监听的端口为websocket
的端口。且必须使用server
监听端口,若使用app
监听端口,只能获取到网页文件而不能进行websocket
连接。
消息推送(emit)
emit
的语法:https://socket.io/docs/server-api/#socket-emit-eventname-args-ackemit
多种推送方式的相关说明不在API
中,而是在下面的页面中做介绍:
https://socket.io/docs/rooms-and-namespaces/
https://socket.io/docs/emit-cheatsheet/
语法:socket.emit(eventName[, ...args][, ack])
eventName
为推送的标志;args
为任意多的推送数据;ack
为一个函数,可选,在客户端应答时可被调用(可确认客户端是否接受到讯息),详见官网例子。
io.emit
io.emit
与io.sockets.emit
等价。将消息推送至所有连接到的客户端。(准确地讲是连接到默认命名空间default namespace
,即/
下的所有客户端。通过io.connection
连接的,都会连接到/
。namespace
很好理解,不做介绍,需要可看官网)
socket.emit
socket.emit
中的socket
为io.on('connection', (socket) => {...})
中回调的参数。此为只向该客户端发送消息。
更多推送方式可看官网,简短易懂。
客户端
首先需要引入js
文件1
2
3
4
5
6
7
8// 直接在静态html文件中写入,无其他要求
<script src="/socket.io/socket.io.js"></script>
// 未遇见,可能Vue,Angular需要使用
const io = require('socket.io-client')
// 在React中使用
import io from 'socket.io-client'
引入后需要const socket = io()
来进行连接。io
为所引入的js
文件暴露的函数。io()
可传入一个连接的url
(string)。不传入则默认为window.location
。更多见文档。
- 接收服务端推送:
socket.on(eventName, ...args [, fn])
其中eventName
为服务端推送对应标志;...args
为推送数据,与服务端对应;fn
为回调函数,可选。
- 推送数据至服务端:
socket.emit()
。语法与服务端的推送一致
注意:客户端和服务端都能进行推送和接收,且语法一致
create-react-app
+ socket.io
开发阶段
使用create-react-app
新建项目后,在命令行中进入文件夹,安装socket.io
:npm i --save socket.io
对于React
,一般可在App.js
中引入socket.io
的js
文件,此时会自动连接:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34import React, { Component } from "react"
// 此处引入
import io from "socket.io-client"
class App extends Component {
constructor() {
super()
this.state = {
msg : false,
// 此处连接到本地的`3001`端口
endpoint : "http://127.0.0.1:3001"
}
}
componentDidMount() {
const { endpoint } = this.state
const socket = io(endpoint)
socket.on("Msg", data => this.setState({ msg : data }))
}
render() {
const { msg } = this.state
return (
<div>
{msg ?
<p>{msg}</p> :
<p>Loading...</p>}
</div>
)
}
}
export default App
若有需要手动连接/断开,可如下操作:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26constructor() {
super()
this.state = {
socket : io('localhost:3001', {
autoConnect: false // 设置为不自动连接
}),
msg : false,
}
this.state.socket.on('Msg', (msg) => {
this.updata(msg)
})
}
updata(msg) {
this.setState({msg : msg})
}
componentWillMount() {
// 连接
this.state.socket.open()
}
componentWillUnmount() {
// 断开
this.state.socket.close()
}
对于服务端,开发阶段可以直接在项目根目录放入server.js
文件,用来提供推送(可不使用express
)1
2
3
4
5
6
7
8
9
10
11
12
13
14const server = require('http').createServer()
const io = require('socket.io')(server)
const port = 3001 // 端口要对应
let emitData = 'emit test'
io.on('connection', (socket) => {
socket.emit('Msg', emitData)
})
server.listen(port, () => {
console.log("Running...")
});
进行测试时只需启动server.js
文件并使用npm start
即可。
部署
正式部署时,一个端口可同时用来进行网页访问和websocket
连接。若不想再单独开启一个端口,可将React
中io()
传入的url
参数清除。
使用npm run build
将React
项目生成静态文件,然后将build
目录复制到服务器项目下,同时将静态目录设置为build
文件夹。如express
:app.use(express.static(__dirname + '/build'))