網絡遊戲開發-客戶端2(自定義websocket協議格式)

Egret官方提供了一個Websocket的庫,能夠讓咱們方便的和服務器長鏈接交互。web

標題寫的時候自定義websocket的協議格式。解釋一下,不是說咱們去動websocket自己的東西,咱們是在websocket的傳輸內容裏面約定一套服務器和客戶的交互格式。json

捋一下思路:小程序

  1. 選擇序列化的方式
  2. 約定一個交互格式
  3. 封裝一個簡單的NetMgr(網絡管理類)

選擇序列化方式:微信小程序

目前主流的序列化方式通常就三種 xml json protobuf,通過考慮,我決定選擇json,緣由是:1.對複雜的格式支持比protobuf好。2.比xml更節約流量。3.由於選擇的時候TypeScript,因此json序列化更方便,我看egret論壇有反應protobuf在微信小程序中有問題。因此綜合一下,就選擇json吧。服務器

約定一個交互格式:微信

格式就三個字段:1.cmd :命令 2. data 數據 3. CmdType:命令類型websocket

class Protocol<T> {

    public cmd: string;

    public data: T;

    public cmdType: CMDTYPE;


}
enum CMDTYPE {
    RECHARGE,
    NET,
    OTHER
}

封裝一個簡單的NetMgr:網絡

封裝NetMgr這個類主要是想把遊戲邏輯和基礎的網絡操做部分屏蔽,經過Egret的事件機制來傳遞網絡數據到界面層。發送數據給服務器,也只操做NetMgr。不會直接接觸websocket。socket

簡單的事件類封裝優化

class NetEvent extends egret.Event {


    public cmd: string = "NetEvent";
    public data: any;
    public constructor(type: string, bubbles: boolean = false, cancelable: boolean = false) {
        super(type, bubbles, cancelable);
    }
}

NetMgr類

// TypeScript file
/**
 * 網絡管理類
 */
class NetMgr extends egret.DisplayObject {

    private socket: egret.WebSocket = new egret.WebSocket();
    static net: NetMgr;

    constructor() {
        super();

    }
    public static GetInstance(): NetMgr {
        if (this.net == null)
            this.net = new NetMgr();
        return this.net;
    }

    public StartSocket(serverip: string, port: number): void {
        if (this.socket.connected) return;
        this.socket.addEventListener(egret.ProgressEvent.SOCKET_DATA, this.onReceiveMessage, this);
        this.socket.addEventListener(egret.Event.CONNECT, this.onSocketOpen, this);
        this.socket.addEventListener(egret.IOErrorEvent.IO_ERROR, this.IOError, this);
        this.socket.addEventListener(egret.Event.CLOSE, this.Close, this);
        this.socket.connect(serverip, port)


    }

    public GetStatus(): boolean {
        return this.socket.connected;
    }



    onReceiveMessage(): void {
        console.log("接收到消息:");
        var msg = this.socket.readUTF();
        console.log(msg);

        let protocol: Protocol<any> = JSON.parse(msg);
        // if (protocol.cmd) {
        try {
            let event = new NetEvent(NetEvent.Net);
            event.cmd = protocol.cmd;
            event.data = protocol;
            this.dispatchEvent(event)
        } catch (error) {
            console.error("網絡事件:" + protocol.cmd + "-處理錯誤")
        }
    }

    Close(): void {
        console.log("鏈接關閉")

    }

    onSocketOpen(): void {

        console.log("網絡鏈接成功");

    }

    IOError(): void {

        console.log("網絡鏈接斷開")


    }

    public Emit<T>(cmd: string, data: T): void {
        if (this.socket.connected) {
            let protocol = new Protocol<T>();
            protocol.cmd = cmd;
            protocol.data = data;
            this.socket.writeUTF(JSON.stringify(protocol));
        }

    }


}

簡單的網絡操做和序列化就這樣了,後面還有斷網重連之類的,就後面再優化。(我通常作東西都是先實現,再優化)

如何使用呢??

1.接收服務器的數據

NetMgr.GetInstance().addEventListener(NetEvent.Net, (e: NetEvent) => {
                console.log("接受到網絡派發的事件" + e.data)

            }, this)

2.給服務器發送數據

    let demo = new TestDemo();
                demo.Data = "wocao";
                NetMgr.GetInstance().Emit<TestDemo>("serverAction", demo);

好了,這塊內容就到這裏了

 須要持續關注的大佬,能夠考慮一下進咱們的QQ羣:753357671


相關文章
相關標籤/搜索