大家都知道,小程序的websocket在切入后台5秒左右,会断开链接,或者长时间无数据收发,也会切断链接。
然而心跳数据并不能完全保证链接的正常,
我在这里说一下我的经验,我初中毕业(真的),代码方面写的不好不要见笑。
首先,我为了知道当前的网络是否断了,使用了一个标志位比如 :
var NetworkIsOK = false;
当首次链接打开时比如socket的 onOpen 事件!在这个事件回调中,将NetworkIsOK = true;
同理,如果网络出现错误,在错误的回调中将NetworkIsOK = false;
建立一个发送 发送区数据 暂存站
var SendBuffer =[];
将socket的send 函数包装一下,比如取名SendToServer(data)
在SendToServer中,首先检查网络的状态,如果状态是正常的,则直接调用socket.send()发送数据,
如果不是正常的,则重新链接服务器,并在onOpen事件中检查 SendBuffer.length是否大于 0 ,如果有存入的缓冲数据,则依次发送掉,
以下是部分实际代码,请忽略我垃圾的编程水平!
var app = getApp();/** * 与服务器进行通信的所有操作在此进行 */var Server = {};Server.socket = null; //socket连接句柄Server.isOK = false; //服务器连接状态处理数组Server.event = []; //事件注册处理数组Server.url = 'wss://********'; //服务器地址Server.SendBuffer=[]; //数据包发送缓冲/** * 初始化操作 */Server.Init=function(apps){ console.log('hello server'); app = apps; console.log(app); var Timer; /**执行服务器连接逻辑 */ Server.socket = wx.connectSocket({ url:Server.url }); //132.232.87.229 Server.socket.onOpen(function () { console.log('Server open'); Server.isOK=true; //可以通信了 //显示成功 wx.showToast({ title: '已连接服务器 ', }); Timer = setInterval(function () { Server.startHeart(); }, 1000 * 50); }); Server.socket.onError(function () { console.log('Server error'); Server.isOK = false; //显示成功 wx.showToast({ title: '服务器连接错误', icon:'none' }); //Server.reLink(); clearInterval(Timer); }); Server.socket.onClose(function () { console.log('Server close'); Server.isOK = false; //显示成功 wx.showToast({ title: '服务器连接关闭', icon: 'none' }); //Server.reLink(); clearInterval(Timer); }); Server.socket.onMessage(function (res) { //Server.socketPress.onMessage(res); var message = JSON.parse(res.data); if(!message) return; //空数据 var Operator = message.Operator; var event=Server.event[Operator]; if(event){ event(message); //实际执行 } });
Server.reLink=function(){ var Timer; /**执行服务器连接逻辑 */ Server.socket = wx.connectSocket({ url:Server.url }); //132.232.87.229 Server.socket.onOpen(function () { console.log('Server open'); Server.isOK = true; //可以通信了 //显示成功 wx.showToast({ title: '已连接服务器 ', }); Server.Login();//重新注册登入 Timer = setInterval(function(){ Server.startHeart(); },1000*50); //检查缓冲区是否有未发送数据 while (Server.SendBuffer.length>0){ var data = Server.SendBuffer.pop(); //将用户的code发往服务器 Server.socket.send({ data: data }); console.log('将缓存中的信息发送',data) } }); Server.socket.onError(function () { console.log('Server error'); Server.isOK = false; //显示成功 wx.showToast({ title: '服务器连接错误', icon: 'none' }); //Server.reLink(); clearInterval(Timer); }); Server.socket.onClose(function () { console.log('Server close'); Server.isOK = false; //显示成功 wx.showToast({ title: '服务器连接关闭', icon: 'none' }); //Server.reLink(); clearInterval(Timer); }); Server.socket.onMessage(function (res) { //Server.socketPress.onMessage(res); var message = JSON.parse(res.data); if (!message) return; //空数据 var Operator = message.Operator; var event = Server.event[Operator]; if (event) { event(message); //实际执行 } });};/** * 启动心跳 */Server.startHeart=function(){ if (Server.isOK == false) { Server.reLink(); //重连 return; } var sendData = { Operator: 'Heart', //操作方式 }; var JsonData = JSON.stringify(sendData); // console.log(JsonData); //将用户的code发往服务器 Server.socket.send({ data: JsonData }); Server.addEvent('HeartOK',function(message){ // console.log('心跳OK',message); })}/**用户登陆 */Server.Login=function(ques){ var userOpenId = wx.getStorageSync('openId'); console.log(app); var sendData = { Operator: 'userLogin', //操作方式 userCode: app.userCode, //用户code userInfo: app.userInfo, //用户信息 }; if (userOpenId) { //如果缓存中的有效,就用缓存中的openId发过去给服务器 sendData.userOpenId = userOpenId; console.log('调用缓存openID'); } var JsonData = JSON.stringify(sendData); console.log("登陆数据:", JsonData); // console.log(JsonData); //将用户的code发往服务器 Server.SendData(sendData); /**如果是黑名单用户,禁止使用 */ Server.addEvent('BanLogin',function(message){ if (ques) { ques(); } });};/** * 注册消息执行处理函数 */Server.addEvent=function(eventName,eventHandle){ Server.event[eventName] = eventHandle;}/**注册登入成功处理事件 */Server.addEvent('LoginOK',function(message){ console.log('LOGIN OK'); console.log(message); wx.setStorageSync('openId',message.openId);});/**注册登入失败处理事件 */Server.addEvent('LoginError', function (message) { wx.showModal({ content: '登入失败了!部分功能可能无法使用,可能是网络原因,也可能是没有获得授权', showCancel: false, success: function (res) { if (res.confirm) { //console.log('用户点确定'); } } });});/** * 创建帖子 */Server.CreateInvitation=function(table,image,text,isRichText){ var sendData = { Operator: 'CreateInvitation', //操作方式 isRichText:isRichText,//是否为富文本 Table:table,//标题 Image:image,//图片地址 Text:text,//文本内容 }; Server.SendData(sendData);};/** * 从服务器获取贴子 */Server.GetInvitation=function(id,mode,time,limt,skip,success){ var sendData = { Operator: 'GetInvitation', //操作方式 id:id, //使用帖子ID的查询方式 mode:mode, //操作模式 time:time, //时间查询时使用的时间 limt:limt, //分页查询时需要获取的贴子数量 skip:skip, //需要跳过的帖子数量 }; //var JsonData = JSON.stringify(sendData); Server.SendData(sendData); /**注册登入成功处理事件 */ Server.addEvent('GetInvitationOK', function (message) { console.log('GetInvitationOK'); var data = message.data; var serverTime=message.serverTime; if(success) success(data,serverTime); //回调执行 });}/** * 创建帖子评论 */Server.CreateInvitationComment=function(_id,text,success){ var sendData = { Operator: 'CreateInvitationComment', //操作方式 id:_id, //使用帖子ID的查询方式 text:text,//评论内容 }; Server.SendData(sendData); /**注册登入成功处理事件 */ Server.addEvent('CreateInvitationCommentOK', function (message) { console.log('CreateInvitationCommentOK'); var data = message.data; if (success) success(data); //回调执行 });};/** * 给帖子点赞 */Server.LoveInvitation=function(_id,success){ var sendData = { Operator: 'LoveInvitation', //操作方式 id:_id, //使用帖子ID的查询方式 }; Server.SendData(sendData); /**注册登入成功处理事件 */ Server.addEvent('LoveInvitationOK', function (message) { console.log('LoveInvitationOK'); if (success) success(); //回调执行 });}/** * 向服务器发送数据,数据类型为任意数据, * 如果服务器断线,则自动重连服务器,数据被暂存,重连成功后将被发送 */Server.SendData=function(data){ if (Server.isOK == false) { Server.reLink(); //重连 //将未发送数据存入Buffer var JsonData = JSON.stringify(data); Server.SendBuffer.push(JsonData); return; }else{ //否则直接给服务器发送数据 var JsonData = JSON.stringify(data); Server.socket.send({ data: JsonData }); }}//暴露接口module.exports.Server = Server; |

这个切入点很好,不过,可以事先阐述一下你的方案是什么,已经解决的问题是啥?这样后面的读者能更好的了解你的文章目的。
推荐下次 可以将代码 拆分为一段一段来讲,其实,分享也是一种学习方式。
学历是社会给你的标签,不是你自己给你的标签。
加油。
嗯,我的想法很简单,就是保证数据都能被有效的发送,所以整了这么个, 就目前的使用来看效果比较好,即使断线了出错了,只要一有数据发送,就能重新连接,然后发送数据, 因为是直接复制的项目代码,所以里面还有消息的处理方式,看起来不够简单
有没有wss域名搭建的教程啊 求分享
还行 后台也做过websocket,对长连接更加深入,代码还有很多优化的余地,es5的写法比较多,距离老司机还有点距离
~是吗,忘大神指教。我是刚学的javascript~
刚学的就会这些了 厉害