手机版

微信小程序开发系列分析《三》 websocket

时间:2021-12-20 来源:互联网 编辑:宝哥软件园 浏览:

为什么需要websocket?传统的实时互动游戏,或者是服务器主动发送消息(比如推送服务),如果你想在微信上做,可能会用到轮询,但是这样太耗费资源,大量的请求也增加了服务器的负担,而且延迟问题严重。如果是自己开发的app,为了解决这些问题,很多团队会搭建自己的socket,使用tcp长链接和自定义协议与服务器进行相对实时的数据交互。有能力的团队,这样自然没有大问题。但是小团队可能要花很多时间调试,解决很多问题,从成本上来说是不值得的。

H5引入webSocket解决网页链接长的问题,微信小程序也支持websocket。这是一个非常重要的特性,所以本系列文章将专门讨论websocket。WebSocket本质上是一个TCP连接,提供全双工数据传输。一方面可以避免轮询带来的频繁连接建立和断开的性能损失;另一方面,数据可以实时双向传输(因为是长链路),WebSocket允许跨域通信(存在潜在的跨域安全问题,需要服务器解决)。目前IE之外的浏览器已经很好的支持webSocket了,稍微推一下微信小程序就会更受欢迎。

让我们设计一个新的演示,一个有趣的小游戏,多人版扫雷,准确地说,多人版黄金采矿。背景码:https://github.com/jsongo/mime-server前端码:https://github.com/jsongo/wx-mime

微信小程序开发系列分析《三》websocket(图1)游戏规则如下:变雷为金,挖金时加一分,每人轮流一次(A转B,B挖A后不能再点击)。即使你击中的黄金是你的,它也不会爆炸。游戏将继续进行,直到地里所有的金子都被挖出来。就像扫雷一样,数字也表示周围有几块金子,然后用户可以根据场上已经翻出来的数字来猜测哪个格子可能有金子。

这款互动游戏的难点在于,用户的点击要传输到服务器,服务器要实时推送给其他玩家的应用。此外,用户自己也要接收对方操作的实时数据,以免在点上复制同一个网格。简单来说,你要向服务器报告操作,服务器也要实时向你推送消息。为了简化整个模型,我们规定玩家必须轮流点击。玩家A点击完毕后,轮到玩家B,玩家B操作完毕后,玩家A可以点击。我们通过几个步骤来实现这个功能。

一、实现思路

1.第一步,我们要老师做一个扫雷的地图场景。这个算法比较简单,简单描述一下。随机取一行一列,定位一个网格,标记为金色(-1表示金色)。MimeCnt代表要生成的黄金数量,mimeCnt随机方块也以同样的方式循环标记。生成后,用一个循环扫描这些-1个方块,并在它周围的所有方块上加1。当然,只有非金方才能加1。把代码放在这里。

微信小程序开发系列分析《三》websocket(图2)

其中,increaseArround用于给这个黄金网格周围的所有方块加1,实现相对简单:

微信小程序开发系列分析《三》websocket(图3)

执行genMimeArr(),并随机生成以下结果:

微信小程序开发系列分析《三》websocket(图4)

-1表示黄金。好像没什么问题。接下来,我们将访问webSocket。(这是js版本。实际上,生成地图场景的工作是在后台完成的。这个js版本只是演示,但是算法是一样的。)

2.我们需要一个支持webSocket的服务器。在这个例子中,我们使用python的tornado框架(tornado提供tornado.websocket模块)。当然,读者也可以使用专为webSocket设计的js语言的服务器socket.io,使用起来非常简单,对于不支持webSocket的浏览器也很有用。

供了兼容(flash或comet实现)。

笔者本人比较喜欢使用tornado,做了几年后台开发,使用最多的框架之一的就是它,NIO模型,而且非常轻量级,同样的rps,java可能需要700-800M的内存,tornado只要30-40M,所以在一台4G内存的机子上可以跑上百个tornado服务,而java,对不起,只能跑3个虚拟机。微服务的时代,这一点对小公司很重要。当然如果读者本人对java比较熟悉的话,也可以选择netty框架尝试一下。

webSocket用tornado的另一个好处是,它可以在同一个服务(端口)上同时支持webSocket及http两种协议。tornado的官方demo代码中展示了怎么实现同时使用两种协议。在本游戏中,可以这么用:用户进入首页,用http协议去拉取当前的房间号及数据。因为首页是打开最多的,进了首页的用户不一定会玩游戏。所以首页还没必要建立webSocket链接,webSocket链接主要用来解决频繁请求及推送的操作。首页只有一个请求操作。选了房间号后,进去下一个游戏页面再开始建立webSocket链接。

3、客户端使用微信小程序开发工具,直接连接是会报域名安全错误的,因为工具内部做了限制,对安全域名才会允许连接。所以同样的,这里我们也继续改下工具的源码,把相关的行改掉就行修改方式如下:找到asdebug.js的这一行,把它改成: if(false)即可。

if (!i(r, "webscoket"))

懒得修改的读者可以直接使用我破解过的IDE。 发起一个websocket链接的代码也比较简单:

wx.connectSocket({    url: webSocketUrl,});

在调用这个请求代码之前,先添加下事件监听,这样才知道有没有连接成功:

wx.onSocketOpen(function(res){    console.log('websocket opened.');});

连接失败的事件:

wx.onSocketError(function(res){  console.log('websocket fail');})

收到服务器的消息时触发的事件:

wx.onSocketMessage(function(res){    console.log('received msg: ' + res.data);})

当链接建立之后,发送消息的方法如下:

wx.sendSocketMessage({    data:msg})

消息发送由于建立链接是需要几次握手,需要一定的时间,所以在wx.connectSocket成功之前,如果直接wx.sendSocketMessage发送消息会报错,这里做一个兼容,如果连接还没建立成功,则用一个数组来保存要发送的信息;而链接第一次建立时,把数据遍历一遍,把消息拿出来一个个补发。这个逻辑我们封装成一个send方法,如下:

function sendSocketMessage(msg) {    if (typeof(msg) === 'object') { // 只能发送string        msg = JSON.stringify(msg);    }    if (socketOpened) { // socketOpened变量在wx.onSocketOpen时设置为true        wx.sendSocketMessage({            data:msg        });    } else { // 发送的时候,链接还没建立        socketMsgQueue.push(msg);    }}

二、demo功能解析

1、首页entry为了简化模型,把重点放在webSocket上,我们把首页做成自己填写房间号的形式。读者如果自己有时间和能力的话,可以把首页做成一个房间列表,并显示每个房间有多少人在玩,只有一人的可以进去跟他玩。甚至后面还可以加上观

版权声明:微信小程序开发系列分析《三》 websocket是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。