## API記憶
`broadcast`是`socket`下的方法而不是`io`下的,因為broadcast是向除了自己以外的所有人廣播,而socket就表示(自己)用戶當前的連接。
> broadcast.to(`<room>`).emit(event,data);
>io.of(namespace).in(`<room>`).emit(event,data)
io比broadcast強的一點在于它能在一個namespace下向另一個namespace發送消息(雖然包括自己)
服務器可以這樣劃分namespcae
```
io.on('connection', socket => {}
io.of('/news').on('connection', socket => {}
```
對應客戶端
```
let socket = io('http://localhost/');
let socket = io('http://localhost/news');
```
## 安裝
```
npm i socket.io
npm i socket.io-client
```
## 和express配合
```
const server = require('http').Server(app); //用原生http包裹express app
const io = require('socket.io')(server); //再用socket包裹
```
這樣的話express中注冊的其它路由仍然能照常訪問并且還能連接上socket
我們可以綁定給io綁定`connection`事件
```
io.on('connection', function (socket) { //socket當前用戶的連接
console.log('user login');
socket.on('sendmsg',function(data){ //監聽客戶端的emit
...
});
// console.log(data);
io.emit('recvmsg',data); //recvmsg 自定義的一個事件 向客戶端廣播 需在客戶端監聽
})
});
```
其中`sendmsg`和`recvmsg`都是用戶自定義的事件
## 客戶端的使用
```
import io from 'socket.io-client';
const socket = io('ws://localhost:9093'); //跨域的話需要手動指定
```
### emit
和服務端一樣都有emit方法
```
export function sendMsg({from,to,msg}){
return dispatch=>{
socket.emit('sendmsg', {from, to, msg});
}
}
```
#### send
send是對emit的封裝
等于
```
socket.emit('message',...);
```
### on
和服務端一樣都有on方法
```
socket.on('recvmsg', (data) => { //recvmsg 由服務端自定義的一個事件
console.log(data)
this.setState({
msg: [...this.state.msg, data.text]
})
});
```
## connect和connection
connect是客戶端綁定的事件,connection是服務端綁定的事件
## 關于客戶端引用路徑
服務端運行后會在根目錄動態生成socket.io的客戶端js文件 客戶端可以通過固定路徑`/socket.io/socket.io.js`添加引用
客戶端加載socket.io文件后會得到一個全局的對象io
connect函數可以接受一個url參數,url可以socket服務的http完整地址,也可以是相對路徑,如果省略則表示默認連接當前路徑 創建index.html文件
## 事件匯總
事件名稱 含義
connection 客戶端成功連接到服務器
message 接收到客戶端發送的消息
disconnect 客戶端斷開連接
error 監聽錯誤
## 劃分命名空間
### 服務器端劃分命名空間
```
io.on('connection', socket => {}
io.of('/news').on('connection', socket => {}
```
### 客戶端連接命名空間
```
let socket = io('http://localhost/');
let socket = io('http://localhost/news');
```
## 房間
### 進入房間
```
socket.join('chat');//進入chat房間
```
### 離開房間
```
socket.leave('chat');//離開chat房間
```
## 廣播
### 向所有人廣播
```
io.emit('message','全局廣播');
```
### 向除了自己外的所有人廣播
```
socket.broadcast.emit('message', 'default server: ' + msg);
socket.broadcast.emit('message', 'news server: ' + msg);
```
### 向包括自己的所有人廣播
```
io.sockets.emit('message', 'default server: ' + msg);
io.of('/news').emit('message', 'news server: ' + msg);
```