基于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)