基於socket.io 協議的長連接通信——交互模塊
需求
大屏展示數據,通過手機端H5頁面操作控制大屏上的模塊,實現聚焦高亮或跳轉
1、前端react 項目中 安裝客戶端模塊
npm/cnpm i socket.io-client –S
2、服務方面
目前解決方案:啟動基於node的一個聊天dome 當做服務
后期解決方案:開發Java版的基於socket.io 的服務
3、封裝的工具方法
3.1 主要有socket.js 、 socket-common.js兩個文件
3.2 socket-common.js 中內容
主要定義一些變量名稱
//前后端共同定義消息類型,發出相應消息和監聽相應消息類型必須匹配
export const C_IMEVT_COMMON$DATA = '2';
/**
由客戶端發出 - 協議類型:發送通用數據(注意:此事件一定要與服務端protocal-type.js中定義的保持一致!)
**/
export const S_IMEVT_DUPLICATED = 's_evt.duplicated';
/**
由服務端發出 - 協議類型:重復登陸被踢消息(注意:此事件一定要與服務端protocal-type.js中定義的保持一致!)
**/
export const S_IMEVT_ILLEGAL = 's_evt.illegal';
/**
由服務端發出 - 協議類型:非法連接被拒絕服務事件(即服務將未帶有合法認證信息的socket踢掉前發出的事件通知,防止非法連接和攻擊)
(注意:此事件一定要與服務端protocal-type.js中定義的保持一致!)
**/
3.3 socket.js中內容
主要是一些屬性和調用的方法 (沒有集成登錄權限判斷的方法)
1、_socket //實例對象
2、callback_showChatMessage //收到服務端的回調函數
3、Socket.initConnect 初始化連接方法
4、Socket.sendData 將消息通過websocket發送出去
5、Socket.disconnectSocket 客戶端主動斷開客戶端socket連接
4、socket.initConnect 里的方法
發起首次連接和認證
this._socket = SocketIOClient.connect(wsUrl, {
query: 'token='+JSON.stringify(data),//至於query 后期可根據我們的業務是否需要
forceNew:true, // 加了此選項才能讓客戶端socketio.disconnect()生效!
secure:supportSSL?true:false // 是否支持SSL/TLS
});
//成功時的回調
this._socket.on('connect', function () {
that.logInfo('[E] 本客戶端的Socket connect 事件已經觸發', true)
});
//斷開時的回調
this._socket.on('disconnect', function (data) {// data content is "io server disconnect"
that.logInfo('[E] 本客戶端的Socket disconnect 事件已經觸發【END】!',true)
});
//重連接時出錯
this._socket.on('connect_error', function (data) {
that.logInfo('[E] 本客戶端 connect_error 事件已觸發'+JSON.stringify(data), true);
});
//超時
this._socket.on('connect_timeout', function () {
that.logInfo('[E] 本客戶端 connect_timeout 事件已觸發', true);
});
this._socket.on('error', function (err) {
that.logInfo('[E] 本客戶端 error 事件已經觸發'+err, true);
});
//重新連接到服務器
this._socket.on('reconnect', function () {
that.logInfo('[E] 本客戶端 reconnect 事件已觸發', true);
});
//不間斷嘗試重連接
this._socket.on('reconnect_attempt', function () {
console.log(this)
that.logInfo('[E] 本客戶端 reconnect_attempt 事件已觸發', true);
});
this._socket.on('reconnect_failed', function () {
that.logInfo('[E] 本客戶端 reconnect_failed 事件已觸發', true);
});
//報錯時走這個方法
this._socket.on('reconnect_error', function () {
that.logInfo('[E] 本客戶端 reconnect_error 事件已觸發', true);
});
//心跳
//連接存活驗證
//發出
this._socket.on('ping', function () {
that.logInfo('[E] 心跳請求已發出 →', true);
});
//收到
this._socket.on('pong', function () {
that.logInfo('[E] 心跳響應已收到 ←', true);
});
//監聽C_IMEVT_COMMON$DATA類型的消息
this._socket.on(C_IMEVT_COMMON$DATA, function (p) {
that.logInfo('收到消息:'+JSON.stringify(p), true);
// 將收到的消息通知應用層顯示出來
that.callback_showChatMessage(p);
});
5、在react項目中使用說明
我是在common文件夾中放置socket.js 、 socket-common.js
1、在組件中 import Socket from '../common/socket' //路徑自己寫
2、在 componentDidMount生命周期里initConnect 並寫入回調
//例如:
Socket.initConnect('http://192.168.7.4:3000',{
loginUserId: "2437266454@qq.com"},true)
//寫入回調,
//給socket.js callback_showChatMessage 屬性賦值回調
Socket.callback_showChatMessage = function(data){
console.log(data)
}
3、send 數據
在發送端 因為使用uuid 所以 npm i uuid –S
在頁面 import uuid from ‘uuid’
例如
let obj = {
}
//因為目前利用的是IM官方提供的基於node服務的dome,后期可根據我們的業務定義需要傳遞的參數
let data = {
dataContent:JSON.stringify(obj), //發送的內容 //由於目前定義的消息類型只支持字符串,后期可跟后台重新定義
fp: uuid.v1(), //生成唯一標識 //通常我們使用基於時間戳 v1() 生成的UID,隨機生成 v4() 還是有一定幾率重復的。
from: "666666@qq.com", //發消息的賬戶名稱
to: "2437266454@qq.com", //收消息的賬戶名稱
type: "2", //定義的消息類型
}
Socket.sendData(data)