文章大綱
我們在 App 中如果 App 是在背景狀態,可以使用手機原生的 notification 進行即時通知,但是如果App目前是打開的狀態,想要及時通知,就需要使用 websocket。
在前台RN專案訂閱後端的 socket 服務,必須要跟後端配合,才能順利接收到資料,下一篇文章會分享如何使用 express + socket.io 發送訊息。
package版本 :
- React Native
0.63.3
- socket.io-client
2.3.1
大綱 :
- 安裝 Socket.io
- connect socket
- subscribe
安裝 Socket.io
$ yarn add socket.io-client
connect socket
要先確定後端開給你的 socket 網址,因為通常不會跟 restful api 放在同一個接口。
如果是登入狀態下要訂閱,通常後端會需要你提供使用者token
,所以連線時要一併傳到後端。
因為我想要使用者在進去首頁後才開始接收訊息,避開登入那些頁面,所以整個socket程式碼的部分就寫在Home.js
,沒有放在App.js
。
我會在最下面放整頁程式碼,這邊先一步一步說明紀錄一下。
引入套件 :
import io from 'socket.io-client';
宣告變數放你的 socket 實例 :
import React, {
useEffect,
useState
} from 'react';
const Home = () => {
const [ws, setWs] = useState(null);
}
創建 socket 實例的寫法 :
io(API_HOST, { path: '/ws', query: { token: auth.userToken } })
API_HOST
是我放在.env
環境變數的api網址,就看後端給你的網址是啥。
path
就是後面的 endpoint,這邊都是看後端給你的網址去決定。
token
或其他資料可以用query
參數帶給後端。
所以你可以把它整個放進剛剛宣告的state
中。
useEffect(() => {
setWs(io(API_HOST, { path: '/ws', query: { token: auth.userToken } }));
}, [ws]);
連線到socket server寫法 :
ws.on('connect', () => {
console.log('client connect success');
});
ws.on('error', error => {
console.log(error);
});
ws
就是剛剛宣告的state
。
subscribe
連線成功後要在他的 callback function 內去訂閱頻道,這就要看你跟後端協議的頻道名稱,前後端有對上才收得到,也就是說一個網站可以有各種不同頻道。
訂閱頻道寫法 :
ws.on('getOrder', function (msg) {
console.log(msg);
});
只是這個寫法要放在 on connect 的 callback 中。
like this :
ws.on('connect', () => {
console.log('client connect success');
ws.on('getOrder', function (msg) {
console.log(msg);
});
});
getOrder
就是我的頻道名稱,後端也必須針對getOrder
發送訊息,才可以收到。
所以這邊我們可以把整個連線初始化的流程寫成一個 function。
const initConnectSocket = () => {
ws.on('connect', () => {
console.log('client connect success');
ws.on('getOrder', function (msg) {
console.log(msg);
if (msg && msg.hasOrder) {
Alert({ title: '有新訂單!', onOk: getClientRequest });
}
});
});
ws.on('error', error => {
console.log(error);
});
};
然後在剛剛初始化的useEffect
做防呆的判斷 :
useEffect(() => {
ws
? initConnectSocket()
: setWs(io(API_HOST, { path: '/ws', query: { token: auth.userToken } }));
return () => {
ws && ws.close();
};
}, [ws]);
記住要在
useEffect return
的時候取消訂閱 socket。
完整代碼如下 :
import React, {
useEffect,
useState
} from 'react';
import io from 'socket.io-client';
const Home = () => {
const [ws, setWs] = useState(null);
useEffect(() => {
ws
? initConnectSocket()
: setWs(io(API_HOST, { path: '/ws', query: { token: auth.userToken } }));
return () => {
ws && ws.close();
};
}, [ws]);
const initConnectSocket = () => {
ws.on('connect', () => {
console.log('client connect success');
ws.on('getOrder', function (msg) {
console.log(msg);
if (msg && msg.hasOrder) {
Alert({ title: '有新訂單!', onOk: getClientRequest });
}
});
});
ws.on('error', error => {
console.log(error);
});
};
}
export default Home;
發表評論
想要加入討論嗎?請盡情發表您的想法!