Cocos creator之網(wǎng)絡(luò)通信

開發(fā)一個(gè)網(wǎng)絡(luò)游戲,難免要處理網(wǎng)絡(luò)通信。有幾點(diǎn)問題需要注意:
1.服務(wù)端為了快速開發(fā)可能前期使用http通信,后面再改成websocket/socket。
2.同時(shí)存在http和websocket/socket通信
3.通信數(shù)據(jù)格式可能需要隨時(shí)替換為json或protocol buffer,可能需要添加額外頭部。
4.在新手引導(dǎo)里使用本地?cái)?shù)據(jù)做模擬,請(qǐng)求不需要發(fā)送給后端。
5.重連后數(shù)據(jù)簡(jiǎn)單同步
針對(duì)第一、二個(gè)問題,我在設(shè)計(jì)通信模塊時(shí)會(huì)考慮將通信盡量抽象為統(tǒng)一的對(duì)外接口,在游戲啟動(dòng)時(shí)通過(guò)不同的驅(qū)動(dòng)器創(chuàng)建實(shí)例(如果只使用一種通信方式,使用單一實(shí)例)。
public constructor(driver: ConnectDriver) {
this._driver = driver;
}
先定義通用的網(wǎng)絡(luò)通信數(shù)據(jù)結(jié)構(gòu)。其中請(qǐng)求分為數(shù)據(jù)和控制兩種類型,用于區(qū)分心跳、登錄、重連
/**
* 請(qǐng)求類型
*/
export enum RequestType {
DATA = 1,
CTRL
}
/**
* 網(wǎng)絡(luò)通信數(shù)據(jù)結(jié)構(gòu)
*/
export interface NetData {
seq?: number; // 序列號(hào)
mod: number; // 模塊
cmd: number; // 命令
path?: string; // 路徑
data?: any; // 數(shù)據(jù)
tmpData?: any; // 數(shù)據(jù)處理器臨時(shí)數(shù)據(jù)
status?: number; //狀態(tài)碼
type?: RequestType; //請(qǐng)求類型
}
然后定義通用的對(duì)外接口
public open(url: string, port: number, isBinary: boolean, timeout: number, retryCount: number, params: any, cb: (succ: boolean) => void): void {}
public close(): number {}
public reopen(cb: (succ: boolean) => void): void {}
public sendData(data: NetData, params: HttpReq | any, succCb: (data: NetData) => void, failedCb: (code: number, reason: string) => void): void {}
public resendNotRecv(): void {}
其中resendNotRecv用于重連后發(fā)送沒有收到響應(yīng)的包,后端根據(jù)序列號(hào)決定是否處理。
這里沒有對(duì)推送的處理,實(shí)際上推送是接收到服務(wù)端數(shù)據(jù)后,調(diào)用廣播給監(jiān)聽者。下面定義監(jiān)聽者
/**
* 網(wǎng)絡(luò)連接事件監(jiān)聽接口
*/
export interface ConnectEventListener {
onOpen(driver: ConnectDriver);
onClosed(driver: ConnectDriver);
onError(driver: ConnectDriver, msg: string);
onSendStart(driver: ConnectDriver);
onRecvEnd(driver: ConnectDriver);
}
/**
* 網(wǎng)絡(luò)事件監(jiān)聽接口
*/
export interface NetEventListener extends ConnectEventListener {
onPush(driver: ConnectDriver, data: NetData): void;
}
對(duì)外提供注冊(cè)和移除接口
public addEventListener(listener: NetEventListener): void {}
public removeEventListener(listener: NetEventListener): void {}
針對(duì)第三個(gè)問題,需要定義一些預(yù)處理器,在發(fā)送數(shù)據(jù)前和接收到數(shù)據(jù)后,做攔截預(yù)處理。
/**
* 網(wǎng)絡(luò)通信數(shù)據(jù)處理器接口
*/
export interface NetDataProcessor {
processReqData(data: any): any;
processRespData(data: any): any;
}
對(duì)外提供添加和移除接口,這樣就可以靈活定義通信數(shù)據(jù)格式
public addDataProcessor(processor: NetDataProcessor): void {}
public removeDataProcessor(processor: NetDataProcessor): void {}
針對(duì)第四個(gè)問題,同樣是增加一個(gè)特殊的攔截器,在請(qǐng)求發(fā)送前對(duì)其處理,如果攔截器能處理,就不再發(fā)送給后端。
/**
* 模擬服務(wù)器接口
*/
export interface SimServer {
handleRequest(data: NetData): NetData;
}
對(duì)外提供設(shè)置接口
public setSimServer(server: SimServer): void {}
針對(duì)第五個(gè)問題,所有數(shù)據(jù)請(qǐng)求都有序列號(hào),對(duì)請(qǐng)求進(jìn)行記錄,沒有響應(yīng)的請(qǐng)求包放到一個(gè)隊(duì)列里,重連后重發(fā)這些包給后端處理。
public resendNotRecv(): void {}
更多資源請(qǐng)點(diǎn)擊:https://bycwedu.vipwan.cn/promotion_channels/630597732