默認
打賞 發表評論 66
想開發IM:買成品怕坑?租第3方怕貴?找開源自已擼?盡量別走彎路了... 找站長給點建議
微信小程序中如何使用WebSocket實現長連接(含完整源碼)
閱讀(61760) | 評論(66 收藏16 淘帖1 6

本文由騰訊云技術團隊原創,感謝作者的分享。


1、前言


微信小程序中如何使用WebSocket實現長連接(含完整源碼)_1-2.jpg

微信小程序提供了一套在微信上運行小程序的解決方案,有比較完整的框架、組件以及 API,在這個平臺上面的想象空間很大。騰訊云研究了一番之后,發現微信支持 WebSocket 還是很值得玩味的。這個特性意味著我們可以做一些實時同步或者協作的小程序。

這篇文章分享了一個基于WebSocket長連接的微信小程序——簡單的剪刀石頭布小游戲的制作過程,希望能對想要在微信小程序中使用 WebSocket 的開發者有所幫助。

說明:本文完整源碼請從文末附件下載

2、相關文章


新手入門貼:史上最全Web端即時通訊技術原理詳解
Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE
新手快速入門:WebSocket簡明教程
WebSocket詳解(一):初步認識WebSocket技術
WebSocket詳解(二):技術原理、代碼演示和應用案例
WebSocket詳解(三):深入WebSocket通信協議細節
WebSocket詳解(四):刨根問底HTTP與WebSocket的關系(上篇)
WebSocket詳解(五):刨根問底HTTP與WebSocket的關系(下篇)
WebSocket詳解(六):刨根問底WebSocket與Socket的關系
socket.io實現消息推送的一點實踐及思路
Web端即時通訊技術的發展與WebSocket、Socket.io的技術實踐
Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)
開源框架Pomelo實踐:搭建Web端高性能分布式IM聊天服務器
使用WebSocket和SSE技術實現Web端消息推送
詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket
MobileIMSDK-Web的網絡層框架為何使用的是Socket.io而不是Netty?
理論聯系實際:從零理解WebSocket的通信原理、協議格式、安全性
>> 更多同類文章 ……

3、運行效果


整個游戲非常簡單,連接到服務器后自動匹配在線玩家(沒有則分配一個機器人),然后兩人進行剪刀石頭布的對抗游戲。當對方進行拳頭選擇的時候,頭像會旋轉,這個過程使用 WebSocket 會變得簡單快速。

剪刀石頭布游戲效果如下圖所示:
微信小程序中如何使用WebSocket實現長連接(含完整源碼)_11.gif

4、為什么要用 WebSocket


使用傳統的 HTTP 輪詢或者長連接的方式也可以實現類似服務器推送的效果,但是這類方式都存在資源消耗過大或推送延遲等問題(詳見文章《新手入門貼:史上最全Web端即時通訊技術原理詳解)。而 WebSocket 直接使用 TCP 連接保持全雙工的傳輸,可以有效地減少連接的建立,實現真正的服務器通信,對于有低延遲有要求的應用是一個很好的選擇。

目前瀏覽器對 WebSocket 的支持程度已經很好,加上微信小程序的平臺支持,這種可以極大提高客戶端體驗的通信方式將會變得更加主流。

Server 端需要實現 WebSocket 協議,才能支持微信小程序的 WebSocket 請求。鑒于 SocketIO 被廣泛使用(詳見《Socket.IO介紹:支持WebSocket、用于WEB端的即時通訊的框架),剪刀石頭布的小程序,我們選用了比較著名的SocketIO 作為服務端的實現。

Socket IO 的使用比較簡單,僅需幾行代碼就可啟動服務。

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();

但是,SocketIO 和一些其它的服務器端實現,都有其配套的客戶端來完成上層協議的編碼解碼。但是由于微信的限制(不能使用 window 等對象), SocketIO 的客戶端代碼在微信小程序平臺上是無法運行的。

經過對 SocketIO 通信進行抓包以及研究其客戶端源碼,筆者封裝了一個大約 100 行適用于微信小程序平臺的 WxSocketIO類,可以幫助開發者快速使用 SocketIO 來進行 WebSocket 通信。

const socket = new WxSocketIO();
socket.on('hi', packet => console.log('server say hi: ' + packet.message));
socket.emit('hello', { from: 'techird' });

如果想要使用微信原生的 API,那么在服務器端也可以直接使用 ws 來實現 W3C 標準的接口。不過 SocketIO 支持多進程的特性,對于后續做橫向擴張是很有幫助的。騰訊云在后面也會有計劃推出支持大規模業務需求的 WebSocket 連接服務,減小業務的部署成本。

5、通信協議設計


實現一個多客戶端交互的服務,是需要把中間涉及到所有的消息類型都設計清楚的,就像是類似剪刀石頭布這樣一個小程序,都有下面這些消息類型。

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_1.jpg

具體每個消息的參數可以參考源碼里的server/protocol.brief.md

6、服務器邏輯


服務器的邏輯很簡單:

  • 收到用戶請求加入房間(join),就尋找還沒滿的房間:
      - 找到房間,則加入;
      - 沒找到房間,創建新房間。
  • 有用戶加入的房間檢查是否已滿,如果已滿,則:
      - 給房間里每個用戶發送開始游戲的信號(start);
      - 啟動計時器,計時器結束后進行游戲結算。
  • 游戲結算:
      - 兩兩之間 PK,贏方分數加一,輸方減一,最終得每個玩家基本得分 x;
      - 對于每個玩家,如果分數 x 大于 0,則視為勝利,連勝次數加一,否則連勝次數歸零;
      - 本局得分為分數 x 乘以連勝次數。
  • 發送本局游戲結果給房間里的每位玩家。

7、微信小程序端的實現


微信小程序直接使用上面的協議,針對不同的場景進行渲染。整體的狀態機如下。

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_3.png

狀態機整理清楚后,就是根據狀態機來控制什么時候發送消息,接到消息后如何處理的問題了。具體實現請參照 app/pages/game/game.js里的源碼。

8、部署和運行


拿到了本小程序源碼的朋友可以嘗試自己運行起來(完整源碼請從文末附件下載)。

8.1整體架構


微信小程序中如何使用WebSocket實現長連接(含完整源碼)_1.png

小程序的架構非常簡單,這里有兩條網絡同步,一條是 HTTPS 通路,用于常規請求。對于 WebSocket 請求,會先走 HTTPS 后再切換協議到 WebSocket 的 TCP 連接,從而實現全雙工通信。

8.2準備域名和證書


在微信小程序中,所有的網絡請求受到嚴格限制,不滿足條件的域名和協議無法請求,具體包括:

  • 只允許和在 MP 中配置好的域名進行通信,如果還沒有域名,需要注冊一個
  • 網絡請求必須走 HTTPS 協議,所以你還需要為你的域名申請一個證書
  • 域名注冊好之后,可以登錄微信公眾平臺配置通信域名了。

設置域名和證書如下圖所示:
微信小程序中如何使用WebSocket實現長連接(含完整源碼)_2.png

8.3云主機和鏡像部署


剪刀石頭布的服務器運行代碼和配置已經打包成騰訊云 CVM 鏡像,大家可以直接使用

騰訊云用戶可以免費領取禮包,體驗騰訊云小程序解決方案。

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_3.png
▲ 設置鏡像

鏡像已包含「剪刀石頭布」和「小相冊」兩個小程序的服務器環境與代碼,需要體驗兩個小程序的朋友無需重復部署。

8.4配置 HTTPS


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

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_4.png
▲ Nginx 中配置證書

配置完成后,即可啟動 nginx。

8.5域名解析


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

在騰訊云注冊的域名,可以直接使用云解析控制臺來添加主機記錄,直接選擇上面購買的 CVM。

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_5.png
▲ 修改 DNS 記錄

解析生效后,我們在瀏覽器使用域名就可以進行 HTTPS 訪問。

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_6.png
▲ HTTPS 效果

8.6啟動 WebSocket 服務


在鏡像的 nginx 配置中(/etc/nginx/conf.d),已經把 /applet/websocket的請求轉發到http://127.0.0.1:9595 處理。我們需要把 Node 實現的 WebSocket 服務在這個端口里運行起來。

進入鏡像中源碼位置:
cd /data/release/qcloud-applet-websocket

使用pm2 啟動服務:
pm2 start process.json

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_7.png

8.7啟動微信小程序


在微信開發者工具中修改小程序源碼中的 config.js 配置,把通訊域名修改成上面申請的域名。完成后點擊調試即可連接到 WebSocket 服務進行游戲。

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_11.png

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

微信小程序中如何使用WebSocket實現長連接(含完整源碼)_9.jpg
▲ 成功效果

9、附件下載(完整源碼)


微信小程序剪刀石頭布小游戲完整源碼-(52im.net).zip (968.78 KB , 下載次數: 705 , 售價: 3 金幣)

即時通訊網 - 即時通訊開發者社區! 來源: - 即時通訊開發者社區!

上一篇:運營級仿微信仿陌陌仿快手app源碼出售轉讓下一篇:從HTTP/0.9到HTTP/2:一文讀懂HTTP協議的歷史演變和設計思路

本帖已收錄至以下技術專輯

推薦方案
評論 66
學習了,收藏
簽名: 不想上班,啦啦啦
學習了,厲害!!!
簽名: 第一次簽到
引用:飛飛 發表于 2018-07-02 15:10
學習了,厲害!!!

哈哈
簽名: 明天出發去鹽城,線下面基會要開始了
學習了,謝謝
路過
學習下
學習了
學習了,收藏
厲害了老鐵 學習中
學習學習
學習學習
學習了,想知道如何在小程序中引入socketio
好資源啊~👍
這個不錯,正需要,感謝🙏
不錯呀
厲害了,老鐵!學習一下。
可以
這個不錯,正需要
學習了,這方面還是很有用處的
簽名: Stay hungry,Stay Foolish
打賞樓主 ×
使用微信打賞! 使用支付寶打賞!

返回頂部
乐彩网17500