用小程序WebSocket做一个开房游戏--原理解析

Posted 超凡软件开发工作室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用小程序WebSocket做一个开房游戏--原理解析相关的知识,希望对你有一定的参考价值。

用小程序WebSocket做一个开房游戏--原理解析

最近看小程序交流群里面很多人在讨论WebSocket的用法,刚好这段时间接触了小程序的WebSocket,但是网上教程不多,遂加入自己的一些想法和实现,写下此篇文章,若有不妥,敬请斧正。




当前浏览器不支持播放音乐或语音,请在微信或其他浏览器中播放 用小程序WebSocket做一个开房游戏--原理解析 用小程序WebSocket做一个开房游戏--原理解析


用小程序WebSocket做一个开房游戏--原理解析



用小程序WebSocket做一个开房游戏--原理解析




WebSocket实现原理

00



浏览器通过发起请求,服务器接收到浏览器的请求,发送给浏览器响应,此时完成了“握手”的过程。在WebSocket API中,浏览器和服务器只需要一次握手,即可进行双向数据传输,也就是他们之间形成了一条双向通道,互相可以发送和接收数据。此时服务器不再被动接收浏览器的请求之后才返回数据,而是可以自主推送数据给浏览器。







小程序客户端API

01


说到底也就是客户端要发起请求,服务端做接收。那么小程序中如何发起一个WebSocket请求呢?当然,答案是翻看小程序官方开发文档,具体请自行翻阅,这里不做解释。

用小程序WebSocket做一个开房游戏--原理解析

这是官方文档中WebSocket的API,各个API的释义看命名就可以很明显的知道用途。那么我们直接看流程吧。


用小程序WebSocket做一个开房游戏--原理解析

首先创建一个房间,此时应该发起一个WebSocket连接,与服务端建立一个长连接。创建房间时随机一个房间ID,再发起WebSocket连接,如下:

用小程序WebSocket做一个开房游戏--原理解析


同时,在建立连接的时候,还要初始化一下出错后的监听回调事件。

用小程序WebSocket做一个开房游戏--原理解析


其中,连接发生错误和连接关闭是两个不同的情况。连接发生错误有可能是服务端在连接成功后,挂掉了,或者因为网络原因,此次连接断开了。连接关闭是指此次连接断开,并会返回断开的原因。


此时就已经建立起了与服务器的WebSocket连接,接下来我们要监听收发消息和处理了。

用小程序WebSocket做一个开房游戏--原理解析


定义了2个方法,只要调用相应的方法即可接收或者发送数据了。




服务端设计

02


难度其实在于服务端的设计,小程序客户端只要处理收到的和发送请求就可以了,可服务端的设计会涉及比较多的层面。我们接下来讨论如何做到开房间的模式。由于个人比较习惯于java,所以用的是java实现的,如果想采用其他语言,相信了解下实现原理,也可以采用其他语言实现了。

对于后端源码的实现,可点击底部的原文链接可以查看一个小demo的实现。看源码比较累,咱们直接解析“开房”实现原理吧。


//新连接
public void afterConnectionEstablished(WebSocketSession webSocketSession)


首先建立起新连接的时候会调用这个方法,此时我们可以做一些数据的初步处理。

用小程序WebSocket做一个开房游戏--原理解析


  1. 首先拿到客户端传上来的参数,sid和roomId。在经过数据库换算后得到当前用户的实体entity,此时还有当前用户连接的一个WebSocketSession,我们可以将他们建立起关系。

  2. 拿到WebSocketSession可以取到WebSocket的id,此id从服务的启动后每个连接自增1,所以服务有效期间内,是唯一的。可以此来做Map的key,建立对应关系。id -> UserConnectInfo(包括用户基本信息、所属房间号、WebSocketSession)

    String id = webSocketSession.getId();


  3. 那么每一次连接获得的WebSocketSession我们都可以获取id,到map里面查找,便知道是新连接或者是哪个用户发起的。

  4. 以roomId为key,将用户实体也丢进去,就可以知道该房间里有哪些用户,在房间众多的情况下,不会造成数据混乱。

    roomId -> List<UserConnectInfo>



//收到消息
protected void handleTextMessage(WebSocketSession session, TextMessage message)

此方法是在客户端调用sendMessage方法时,服务端的响应。

用小程序WebSocket做一个开房游戏--原理解析

服务端在该方法中,调用message.getPayload()即可取到从客户端送上来的data,格式需要自己转换。如果嫌麻烦,用字符串挺好。取当前用户的信息,则使用之前的idToUserMap.get(session.getId());可以获取到当前用户的实体信息了,并且可以获得到该用户是哪个房间的,通过房间id调用roomToUsersMap.get(roomId);就可知道当前房间还有哪些人了。


实例

用小程序WebSocket做一个开房游戏--原理解析

【左图为房主视角,右图为玩家视角】


当房主创建房间时,roomToUsersMap中并没有这个key,所以将创建房间的人定为房主,在UserConnectInfo设置房主标志,以便客户端处理。


用小程序WebSocket做一个开房游戏--原理解析

【左图为房主视角,右图为玩家视角】


当玩家点击准备按钮时,客户端调用了sendMessage()这个方法,并且传入了data:"ready",服务端通过message.getPayload()拿到了“ready”,可以判断是用户点击了准备按钮,此时可以做准备的流程:

1.发送给客户端的消息类型设置为“准备”的枚举。

2.将当前发送准备请求的用户,设置为准备状态。

3.计算已准备的总人数。

4.群发给客户端,告知所有人xx已准备。

用小程序WebSocket做一个开房游戏--原理解析

5.客户端收到通知,通过type判断枚举,确认是ready的流程,就走准备的步骤,将xx用户的状态改为准备,显示出来。



总结:点击开始以及后续的步骤,都可以参考准备过程来做。流程都是客户端发一个请求,服务端判断这个请求是谁,想做什么,做完之后,群发或者单发,客户端接收到数据,进行处理。


//关闭连接
public void afterConnectionClosed(WebSocketSession session, CloseStatus status)

当客户端切断中止WebSocket请求后,服务端会调用这个方法。这个方法就用来去除map中已断开连接的用户。可以用来做到:当房主撤走时,下一个人就是房主。





------有点乱?------


用小程序WebSocket做一个开房游戏--原理解析


画图比较直观点。来,上图。

用小程序WebSocket做一个开房游戏--原理解析


用小程序WebSocket做一个开房游戏--原理解析


对于map的映射关系,不怕,也有图!

用小程序WebSocket做一个开房游戏--原理解析

用小程序WebSocket做一个开房游戏--原理解析



用小程序WebSocket做一个开房游戏--原理解析




服务器Nginx转发设置

03


众所周知,腾讯的限制比较恶心变态,但是你想做,只能遵守他们的规则。http要求是https,当然WebSocket的ws也要求是wss。那么如何满足wss呢?

如果服务器还不支持https的请求,没有申请证书的各位,此处不再讨论。有配置了https证书的童鞋们,如何配置wss呢?ok,百度之。

用小程序WebSocket做一个开房游戏--原理解析

首先需要设置一个default upgrade,这是根据nginx官网来的。


用小程序WebSocket做一个开房游戏--原理解析





-没有了-

用小程序WebSocket做一个开房游戏--原理解析


用小程序WebSocket做一个开房游戏--原理解析

用小程序WebSocket做一个开房游戏--原理解析



大家都在看

┣ 

┣ 

┣ 

┣ 

┣ 


用小程序WebSocket做一个开房游戏--原理解析





一个好尼玛随意的公众号


长按,识别二维码,加关注




以上是关于用小程序WebSocket做一个开房游戏--原理解析的主要内容,如果未能解决你的问题,请参考以下文章

房卡麻将分析之“代开房间”

房卡麻将分析之“代开房间”

用小程序做一个类似于苹果AssistiveTouch功能

WebSocket通信协议基础原理与潜在安全威胁

[教你做小游戏] 用86行代码写一个联机五子棋WebSocket后端

Websocket原理及使用场景