注冊(cè)

小程序WebSocket長(zhǎng)連接應(yīng)用場(chǎng)景,剪刀石頭布小程序怎么開(kāi)發(fā)

2020-09-27
導(dǎo)讀:小程序的架構(gòu)非常簡(jiǎn)單,這里有兩條網(wǎng)絡(luò)同步,一條是 HTTPS 通路,用于常規(guī)請(qǐng)求。對(duì)于 WebSocket 請(qǐng)求,會(huì)先走 HTTPS 后再切換協(xié)議到 WebSocket 的 TCP 連接,從而實(shí)現(xiàn)全雙工通信。...

  小程序的架構(gòu)非常簡(jiǎn)單,這里有兩條網(wǎng)絡(luò)同步,一條是 HTTPS 通路,用于常規(guī)請(qǐng)求。對(duì)于 WebSocket 請(qǐng)求,會(huì)先走 HTTPS 后再切換協(xié)議到 WebSocket 的 TCP 連接,從而實(shí)現(xiàn)全雙工通信。

  1. 準(zhǔn)備域名和證書(shū)

  在微信小程序中,所有的網(wǎng)路請(qǐng)求受到嚴(yán)格限制,不滿足條件的域名和協(xié)議無(wú)法請(qǐng)求,具體包括:

  只允許和在 MP 中配置好的域名進(jìn)行通信,如果還沒(méi)有域名,需要注冊(cè)一個(gè)。

  網(wǎng)絡(luò)請(qǐng)求必須走 HTTPS 協(xié)議,所以你還需要為你的域名申請(qǐng)一個(gè)證書(shū)。

  域名注冊(cè)好之后,可以登錄微信公眾平臺(tái)配置通信域名了。

小程序WebSocket長(zhǎng)連接應(yīng)用場(chǎng)景,剪刀石頭布小程序怎么開(kāi)發(fā)

  2. 云主機(jī)和鏡像部署

  剪刀石頭布的服務(wù)器運(yùn)行代碼和配置已經(jīng)打包成騰訊云 CVM 鏡像,大家可以直接使用。

  騰訊云用戶可以免費(fèi)領(lǐng)取禮包,體驗(yàn)騰訊云小程序解決方案。

  鏡像部署完成之后,云主機(jī)上就有運(yùn)行 WebSocket 服務(wù)的基本環(huán)境、代碼和配置了。

  鏡像已包含「剪刀石頭布」和「小相冊(cè)」兩個(gè)小程序的服務(wù)器環(huán)境與代碼,需要體驗(yàn)兩個(gè)小程序的朋友無(wú)需重復(fù)部署

  3. 配置 HTTPS

  鏡像中已經(jīng)部署了 nginx,需要在 /etc/nginx/conf.d 下修改配置中的域名、證書(shū)、私鑰。

  配置完成后,即可啟動(dòng) nginx。

  nginx

  4. 域名解析

  我們還需要添加域名記錄解析到我們的云服務(wù)器上,這樣才可以使用域名進(jìn)行 HTTPS 服務(wù)。

  在騰訊云注冊(cè)的域名,可以直接使用云解析控制臺(tái)來(lái)添加主機(jī)記錄,直接選擇上面購(gòu)買(mǎi)的 CVM。

  解析生效后,我們?cè)跒g覽器使用域名就可以進(jìn)行 HTTPS 訪問(wèn)。

  5. 啟動(dòng) WebSocket 服務(wù)

  在鏡像的 nginx 配置中(/etc/nginx/conf.d),已經(jīng)把 /applet/websocket 的請(qǐng)求轉(zhuǎn)發(fā)到 http://127.0.0.1:9595 處理。我們需要把 Node 實(shí)現(xiàn)的 WebSocket 服務(wù)在這個(gè)端口里運(yùn)行起來(lái)。

  進(jìn)入鏡像中源碼位置:

  cd /data/release/qcloud-applet-websocket

  復(fù)制代碼

  使用 pm2 啟動(dòng)服務(wù):

  pm2 start process.json

  復(fù)制代碼

  6. 啟動(dòng)微信小程序

  在微信開(kāi)發(fā)者工具中修改小程序源碼中的 config.js 配置,把通訊域名修改成上面申請(qǐng)的域名。完成后點(diǎn)擊調(diào)試即可連接到 WebSocket 服務(wù)進(jìn)行游戲。

  配置完成后,運(yùn)行小程序就可以看到成功搭建的提示!

  為什么要用 WebSocket

  使用傳統(tǒng)的 HTTP 輪詢或者長(zhǎng)連接的方式也可以實(shí)現(xiàn)類似服務(wù)器推送的效果,但是這類方式都存在資源消耗過(guò)大或推送延遲等問(wèn)題。而 WebSocket 直接使用 TCP 連接保持全雙工的傳輸,可以有效地減少連接的建立,實(shí)現(xiàn)真正的服務(wù)器通信,對(duì)于有低延遲有要求的應(yīng)用是一個(gè)很好的選擇。

  目前瀏覽器對(duì) WebSocket 的支持程度已經(jīng)很好,加上微信小程序的平臺(tái)支持,這種可以極大提高客戶端體驗(yàn)的通信方式將會(huì)變得更加主流。

  Server 端需要實(shí)現(xiàn) WebSocket 協(xié)議,才能支持微信小程序的 WebSocket 請(qǐng)求。鑒于 SocketIO 被廣泛使用,剪刀石頭布的小程序,我們選用了比較著名的 SocketIO 作為服務(wù)端的實(shí)現(xiàn)。

  Socket IO 的使用比較簡(jiǎn)單,僅需幾行代碼就可啟動(dòng)服務(wù)。

  export class Server {

  init(path: string) {

  /** Port that server listen on */

  this.port = process.env.PORT;

  /** HTTP Server instance for both express and socket io */

  this.http = http.createServer();

  /** Socket io instance */

  this.io = SocketIO(this.http, { path });

  /** Handle incomming connection */

  this.io.on("connection", socket => {

  // handle connection

  });

  }

  start() {

  this.http.listen(this.port);

  console.log(`---- server started. listen : ${this.port} ----`);

  }

  }

  const server = new Server();

  server.init("/applet/ws/socket.io");

  server.start();

  復(fù)制代碼

  但是,SocketIO 和一些其它的服務(wù)器端實(shí)現(xiàn),都有其配套的客戶端來(lái)完成上層協(xié)議的編碼解碼。但是由于微信的限制(不能使用 window 等對(duì)象), SocketIO 的客戶端代碼在微信小程序平臺(tái)上是無(wú)法運(yùn)行的。

  經(jīng)過(guò)對(duì) SocketIO 通信進(jìn)行抓包以及研究其客戶端源碼,筆者封裝了一個(gè)大約 100 行適用于微信小程序平臺(tái)的 WxSocketIO 類,可以幫助開(kāi)發(fā)者快速使用 SocketIO 來(lái)進(jìn)行 WebSocket 通信。

  const socket = new WxSocketIO();

  socket.on('hi', packet => console.log('server say hi: ' + packet.message));

  socket.emit('hello', { from: 'techird' });

  復(fù)制代碼

  如果想要使用微信原生的 API,那么在服務(wù)器端也可以直接使用 ws 來(lái)實(shí)現(xiàn) W3C 標(biāo)準(zhǔn)的接口。不過(guò) SocketIO 支持多進(jìn)程的特性,對(duì)于后續(xù)做橫向擴(kuò)張是很有幫助的。騰訊云在后面也會(huì)有計(jì)劃推出支持大規(guī)模業(yè)務(wù)需求的 WebSocket 連接服務(wù),減小業(yè)務(wù)的部署成本。

  通信協(xié)議設(shè)計(jì)

  實(shí)現(xiàn)一個(gè)多客戶端交互的服務(wù),是需要把中間涉及到所有的消息類型都設(shè)計(jì)清楚的,就像是類似剪刀石頭布這樣一個(gè)小程序,都有下面這些消息類型。

  具體每個(gè)消息的參數(shù)可以參考源碼里的 server/protocol.brief.md

  服務(wù)器邏輯

  服務(wù)器的邏輯很簡(jiǎn)單:

  收到用戶請(qǐng)求加入房間(join),就尋找還沒(méi)滿的房間

  找到房間,則加入

  沒(méi)找到房間,創(chuàng)建新房間

  有用戶加入的房間檢查是否已滿,如果已滿,則:

  給房間里每個(gè)用戶發(fā)送開(kāi)始游戲的信號(hào)(start)

  啟動(dòng)計(jì)時(shí)器,計(jì)時(shí)器結(jié)束后進(jìn)行游戲結(jié)算

  游戲結(jié)算

  兩兩之間 PK,贏方分?jǐn)?shù)加一,輸方減一,最終得每個(gè)玩家基本得分 x

  對(duì)于每個(gè)玩家,如果分?jǐn)?shù) x 大于 0,則視為勝利,連勝次數(shù)加一,否則連勝次數(shù)歸零

  本局得分為分?jǐn)?shù) x 乘以連勝次數(shù)

  發(fā)送本局游戲結(jié)果給房間里的每位玩家

  復(fù)制代碼

  微信端實(shí)現(xiàn)

  微信小程序直接使用上面的協(xié)議,針對(duì)不同的場(chǎng)景進(jìn)行渲染。整體的狀態(tài)機(jī)如下。

  狀態(tài)機(jī)整理清楚后,就是根據(jù)狀態(tài)機(jī)來(lái)控制什么時(shí)候發(fā)送消息,接到消息后如何處理的問(wèn)題了。開(kāi)發(fā)微信小程序看這里。

重磅推薦:小程序開(kāi)店目錄

第一部分:小商店是什么

第二部分:如何開(kāi)通一個(gè)小商店

第三部分:如何登錄小商店

第四部分:開(kāi)店任務(wù)常見(jiàn)問(wèn)題

第五部分:小商店可以賣(mài)什么

第六部分:HiShop小程序特色功能

第七部分:小程序直播

第八部分:小程序收貨/物流

第九部分:小程序怎么結(jié)算

第十部分:小程序客服

第十一部分:電商創(chuàng)業(yè)

第十二部分:小程序游戲開(kāi)發(fā)