消息导出脚本,收发消息简化
This commit is contained in:
parent
e5fc17d1f6
commit
e245377391
@ -4,3 +4,7 @@ export class PrefabNames {
|
||||
return this.login
|
||||
}
|
||||
}
|
||||
|
||||
export enum EventType {
|
||||
Ws = 'ws-message',
|
||||
}
|
||||
|
@ -2,11 +2,8 @@ import { _decorator, Button, Component, EditBox, Label, Node } from 'cc'
|
||||
import { WsClient } from '../network/wsclient'
|
||||
import { WsConfig } from '../network/wsconfig'
|
||||
import { PbHelper } from '../network/pbHelper'
|
||||
import pb from '../pb/login.js'
|
||||
import pb1 from '../pb/client.js'
|
||||
import pb2 from '../pb/msgId.js'
|
||||
import pb3 from '../pb/service.js'
|
||||
// import * as pb from '../pb/login.d'
|
||||
import { ReqUserLogin, ServiceTypeId, MsgId, RspUserLogin } from '../network/pbExport'
|
||||
import { EventType } from '../constant'
|
||||
const { ccclass, property } = _decorator
|
||||
|
||||
@ccclass('loginPanel')
|
||||
@ -24,11 +21,11 @@ export class loginPanel extends Component {
|
||||
start() {
|
||||
this.loginButton.node.on(Button.EventType.CLICK, this.onLoginButtonClick, this)
|
||||
// 监听websocket消息事件
|
||||
window.addEventListener('ws-message', this.onMessage.bind(this))
|
||||
window.addEventListener(EventType.Ws, this.onMessage.bind(this))
|
||||
}
|
||||
|
||||
protected onDestroy(): void {
|
||||
window.removeEventListener('ws-message', this.onMessage.bind(this))
|
||||
window.removeEventListener(EventType.Ws, this.onMessage.bind(this))
|
||||
}
|
||||
|
||||
// 登录按钮点击处理函数
|
||||
@ -46,7 +43,7 @@ export class loginPanel extends Component {
|
||||
const ws = WsClient.Instance()
|
||||
console.log(typeof ws)
|
||||
if (!ws.IsConnected) {
|
||||
await ws.ConnectAsync(WsConfig.Address[0].Address[0])
|
||||
await ws.ConnectAsync(WsConfig.Address[1].Address[0])
|
||||
if (!ws.IsConnected) {
|
||||
this.statusLable.string = '连接网络失败'
|
||||
return
|
||||
@ -54,33 +51,28 @@ export class loginPanel extends Component {
|
||||
}
|
||||
|
||||
console.log('登陆帐号:', username, '密码:', pwd)
|
||||
console.log('ReqUserLogin:', pb.ReqUserLogin)
|
||||
|
||||
const req = new pb.ReqUserLogin()
|
||||
const req = new ReqUserLogin()
|
||||
req.username = username
|
||||
req.password = pwd
|
||||
req.version = '20250601123030'
|
||||
// const req = pb.ReqUserLogin.create({ username: username, password: pwd, ip: '', deviceId: '', version: '' })
|
||||
const buffer = pb.ReqUserLogin.encode(req).finish()
|
||||
const clinetMsg = new pb1.ClientMsg()
|
||||
clinetMsg.msgId = pb2.MsgId.ReqUserLoginId
|
||||
clinetMsg.data = buffer
|
||||
clinetMsg.serviceTid = pb3.ServiceTypeId.STI_Login
|
||||
const buffer1 = pb1.ClientMsg.encode(clinetMsg).finish()
|
||||
ws.Send(buffer1)
|
||||
const buffer = ReqUserLogin.encode(req).finish()
|
||||
ws.Send(ServiceTypeId.STI_Login, MsgId.ReqUserLoginId, buffer)
|
||||
}
|
||||
|
||||
private onMessage(event: CustomEvent) {
|
||||
try {
|
||||
const message = JSON.parse(event.detail) // 解析消息内容
|
||||
if (message.type === 'loginSuccess') {
|
||||
this.statusLable.string = '登录成功'
|
||||
this.node.active = false
|
||||
} else if (message.type === 'loginError') {
|
||||
this.statusLable.string = '登录失败:' + message.reason
|
||||
const [msgid, buffer] = PbHelper.DecodeClient(event.detail)
|
||||
switch (msgid) {
|
||||
case MsgId.RspUserLoginId:
|
||||
const rsp = PbHelper.Decode(RspUserLogin, buffer)
|
||||
console.log('收到返回消息:', rsp)
|
||||
default:
|
||||
// console.log('收到非json消息:', event.detail)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('收到非json消息:', event.detail)
|
||||
// console.log('解析错误失败:', error)
|
||||
console.log(PbHelper.Uint8ToHex(event.detail))
|
||||
}
|
||||
}
|
||||
|
||||
|
80
assets/scripts/network/pbExport.ts
Normal file
80
assets/scripts/network/pbExport.ts
Normal file
@ -0,0 +1,80 @@
|
||||
// 由 pb-import-export-generator 自动生成,请勿手动修改
|
||||
|
||||
// 导入语句
|
||||
import chat from '../pb/chat.js'
|
||||
import client from '../pb/client.js'
|
||||
import code from '../pb/code.js'
|
||||
import colorgame from '../pb/colorgame.js'
|
||||
import common from '../pb/common.js'
|
||||
import login from '../pb/login.js'
|
||||
import match from '../pb/match.js'
|
||||
import msgId from '../pb/msgId.js'
|
||||
import service from '../pb/service.js'
|
||||
import user from '../pb/user.js'
|
||||
|
||||
// 解构赋值
|
||||
const { ChatType, ReqChat, ChatUser, GameUser, ServiceTypeId } = chat
|
||||
const { ClientMsg } = client
|
||||
const { ErrCode } = code
|
||||
const { ColorPrizeArea, ColorPrizeAreaRange, ColorRoomConfig, ColorType, ColorBetArea, ColorGameStatus, ColorRoomWaitStart, ColorRoomStart, ColorRoomBetting, ColorRoomEndBet, ColorRoomOpenThreeDice, ColorRoomSettle, NtfColorRoomInfo, NtfColorGameStart, NtfColorBetting, ReqColorBetting, RspColorBetting, ColorBetAreaInfo, NtfColorBetAreaInfo, ColorPrizeType, ColorBetAreaMul, NtfColorEndBetting, NtfColorOpenThreeDice, NtfColorSettle, ColorUser, NtfColorBigUser, NtfColorTrend, ColorBigUser, NtfColorMaintain } = colorgame
|
||||
const { NtfKickOutUser, ReqEnterRoom, RspEnterRoom, ReqLeaveRoom, RspLeaveRoom, NtfPayoutFail } = common
|
||||
const { ReqUserLogin, RspUserLogin, NtfUserOnline, NtfUserInService, ReqUserLogout, RspUserLogout, NtfUserOffline } = login
|
||||
const { ReqMatchRoom, RspMatchRoom, NotifyUserEnterRoom } = match
|
||||
const { MsgId } = msgId
|
||||
|
||||
// 导出语句
|
||||
export {
|
||||
ChatType,
|
||||
ReqChat,
|
||||
ChatUser,
|
||||
GameUser,
|
||||
ServiceTypeId,
|
||||
ClientMsg,
|
||||
ErrCode,
|
||||
ColorPrizeArea,
|
||||
ColorPrizeAreaRange,
|
||||
ColorRoomConfig,
|
||||
ColorType,
|
||||
ColorBetArea,
|
||||
ColorGameStatus,
|
||||
ColorRoomWaitStart,
|
||||
ColorRoomStart,
|
||||
ColorRoomBetting,
|
||||
ColorRoomEndBet,
|
||||
ColorRoomOpenThreeDice,
|
||||
ColorRoomSettle,
|
||||
NtfColorRoomInfo,
|
||||
NtfColorGameStart,
|
||||
NtfColorBetting,
|
||||
ReqColorBetting,
|
||||
RspColorBetting,
|
||||
ColorBetAreaInfo,
|
||||
NtfColorBetAreaInfo,
|
||||
ColorPrizeType,
|
||||
ColorBetAreaMul,
|
||||
NtfColorEndBetting,
|
||||
NtfColorOpenThreeDice,
|
||||
NtfColorSettle,
|
||||
ColorUser,
|
||||
NtfColorBigUser,
|
||||
NtfColorTrend,
|
||||
ColorBigUser,
|
||||
NtfColorMaintain,
|
||||
NtfKickOutUser,
|
||||
ReqEnterRoom,
|
||||
RspEnterRoom,
|
||||
ReqLeaveRoom,
|
||||
RspLeaveRoom,
|
||||
NtfPayoutFail,
|
||||
ReqUserLogin,
|
||||
RspUserLogin,
|
||||
NtfUserOnline,
|
||||
NtfUserInService,
|
||||
ReqUserLogout,
|
||||
RspUserLogout,
|
||||
NtfUserOffline,
|
||||
ReqMatchRoom,
|
||||
RspMatchRoom,
|
||||
NotifyUserEnterRoom,
|
||||
MsgId
|
||||
};
|
@ -1,8 +1,4 @@
|
||||
/**
|
||||
*
|
||||
* pb helper
|
||||
*/
|
||||
// import { Message } from 'protobufjs'
|
||||
import { ClientMsg } from '../network/pbExport'
|
||||
|
||||
interface ProtoEncodable<T> {
|
||||
create(data: T): unknown
|
||||
@ -16,9 +12,18 @@ export class PbHelper {
|
||||
const message = protoClass.create(data)
|
||||
return protoClass.encode(message).finish()
|
||||
}
|
||||
static DecodeClient(buffer: Uint8Array): [number, Uint8Array] {
|
||||
const cMsg = ClientMsg.decode(buffer)
|
||||
return [cMsg.msgId, cMsg.data]
|
||||
}
|
||||
static Decode<T>(protoClass: ProtoEncodable<T>, buffer: Uint8Array): T {
|
||||
return protoClass.decode(buffer)
|
||||
}
|
||||
static Uint8ToHex(buffer: Uint8Array): string {
|
||||
return Array.from(buffer)
|
||||
.map((byte) => byte.toString(16).padStart(2, '0'))
|
||||
.join(' ')
|
||||
}
|
||||
}
|
||||
|
||||
// // 假设有一个生成的 Protobuf 类
|
||||
|
@ -1,3 +1,7 @@
|
||||
import { ClientMsg } from '../network/pbExport'
|
||||
import { EventType } from '../constant'
|
||||
import { PbHelper } from '../network/pbHelper'
|
||||
|
||||
export class WsClient {
|
||||
private socket: WebSocket | null = null
|
||||
private url: string = 'ws://echo.websocket.org' // 测试服务器
|
||||
@ -81,19 +85,18 @@ export class WsClient {
|
||||
}
|
||||
|
||||
// 发送消息到服务器
|
||||
Send(message: Uint8Array) {
|
||||
Send(sid: number, msgId: number, msg: Uint8Array) {
|
||||
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
||||
// 如果连接不存在或未打开
|
||||
console.error('websocket未连接,无法发送消息')
|
||||
return false
|
||||
}
|
||||
// var msg: string = ''
|
||||
// if (typeof message == 'string') {
|
||||
// msg = message
|
||||
// } else {
|
||||
// msg = JSON.stringify(message)
|
||||
// }
|
||||
this.socket.send(message)
|
||||
const clinetMsg = new ClientMsg()
|
||||
clinetMsg.msgId = msgId
|
||||
clinetMsg.data = msg
|
||||
clinetMsg.serviceTid = sid
|
||||
const buffer = ClientMsg.encode(clinetMsg).finish()
|
||||
this.socket.send(buffer)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -104,9 +107,16 @@ export class WsClient {
|
||||
}
|
||||
|
||||
// 收到消息回调
|
||||
private onMessage(event: MessageEvent) {
|
||||
console.log('收到消息:', event.data)
|
||||
window.dispatchEvent(new CustomEvent('ws-message', { detail: event.data }))
|
||||
private async onMessage(event: MessageEvent) {
|
||||
try {
|
||||
const buffer = await event.data.arrayBuffer()
|
||||
const uint8Array = new Uint8Array(buffer)
|
||||
// console.log('收到消息:', uint8Array)
|
||||
console.log('收到消息:', PbHelper.Uint8ToHex(uint8Array))
|
||||
window.dispatchEvent(new CustomEvent(EventType.Ws, { detail: uint8Array }))
|
||||
} catch (error) {
|
||||
console.error('解析网络消息失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 连接关闭回调
|
||||
|
@ -6,7 +6,7 @@ class AddressInfo {
|
||||
// 网关配置
|
||||
export class WsConfig {
|
||||
public static Address: Array<AddressInfo> = [
|
||||
{ Name: 'super', Address: ['ws://127.0.0.1:5100', 'ws://127.0.0.1:5101'] },
|
||||
{ Name: 'dev', Address: ['ws://127.0.0.1:5100', 'ws://127.0.0.1:5101'] },
|
||||
{ Name: 'test', Address: ['ws://114.132.124.145:5100', 'ws://114.132.124.145:5101'] },
|
||||
]
|
||||
}
|
||||
|
138
tools/pb_exports.js
Normal file
138
tools/pb_exports.js
Normal file
@ -0,0 +1,138 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
/**
|
||||
* PB 模块导入导出代码生成器
|
||||
* @param {string} pbDir - PB 文件所在的目录路径
|
||||
* @param {string} outputFile - 生成的代码输出文件路径
|
||||
* @param {string} [relativePath='../pb'] - 导入语句中的相对路径
|
||||
*/
|
||||
function generatePbImportsAndExports(pbDir, outputFile, relativePath = '../pb') {
|
||||
try {
|
||||
// 读取 PB 目录下的所有文件
|
||||
const files = fs.readdirSync(pbDir)
|
||||
|
||||
// 过滤出 .js 文件并去除扩展名
|
||||
const jsFiles = files.filter((file) => file.endsWith('.js'))
|
||||
|
||||
if (jsFiles.length === 0) {
|
||||
console.warn(`警告: 在目录 ${pbDir} 中没有找到任何 .js 文件`)
|
||||
return
|
||||
}
|
||||
|
||||
// 生成导入语句
|
||||
const importStatements = jsFiles
|
||||
.map((file) => {
|
||||
const moduleName = file.replace('.js', '')
|
||||
return `import ${moduleName} from '${relativePath}/${moduleName}.js'`
|
||||
})
|
||||
.join('\n')
|
||||
|
||||
// 为每个文件生成导出内容
|
||||
const moduleExports = {}
|
||||
const allExports = new Set()
|
||||
const exportSources = {} // 记录每个导出项的来源
|
||||
|
||||
jsFiles.forEach((file) => {
|
||||
const filePath = path.join(pbDir, file)
|
||||
const code = fs.readFileSync(filePath, 'utf-8')
|
||||
const moduleName = file.replace('.js', '')
|
||||
|
||||
// 提取 $root.X 形式的导出
|
||||
const rootExports = extractRootExports(code)
|
||||
|
||||
// 提取 enum 定义
|
||||
const enumExports = extractEnumExports(code)
|
||||
|
||||
// 合并所有导出
|
||||
const exports = [...rootExports, ...enumExports]
|
||||
|
||||
if (exports.length > 0) {
|
||||
moduleExports[moduleName] = exports
|
||||
|
||||
// 记录导出项的来源
|
||||
exports.forEach((exp) => {
|
||||
if (!exportSources[exp]) {
|
||||
exportSources[exp] = moduleName
|
||||
allExports.add(exp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (allExports.size === 0) {
|
||||
console.warn(`警告: 没有找到任何可导出的类或枚举`)
|
||||
return
|
||||
}
|
||||
|
||||
// 生成解构赋值语句(只包含首次出现的导出项)
|
||||
const destructureStatements = Object.entries(moduleExports)
|
||||
.map(([moduleName, exports]) => {
|
||||
// 过滤出该模块独有的导出项
|
||||
const uniqueExports = exports.filter((exp) => exportSources[exp] === moduleName)
|
||||
if (uniqueExports.length > 0) {
|
||||
return `const { ${uniqueExports.join(', ')} } = ${moduleName}`
|
||||
}
|
||||
return ''
|
||||
})
|
||||
.filter(Boolean) // 移除空字符串
|
||||
.join('\n')
|
||||
|
||||
// 生成导出语句(所有唯一导出项)
|
||||
const exportList = Array.from(allExports)
|
||||
|
||||
// 完整的输出代码
|
||||
const outputCode =
|
||||
`// 由 pb-import-export-generator 自动生成,请勿手动修改\n\n` +
|
||||
`// 导入语句\n${importStatements}\n\n` +
|
||||
`// 解构赋值\n${destructureStatements}\n\n` +
|
||||
`// 导出语句\nexport {\n ${exportList.join(',\n ')}\n};\n`
|
||||
|
||||
// 确保输出目录存在
|
||||
const outputDir = path.dirname(outputFile)
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true })
|
||||
}
|
||||
|
||||
// 写入输出文件
|
||||
fs.writeFileSync(outputFile, outputCode)
|
||||
|
||||
console.log(`成功生成 PB 导入导出代码到 ${outputFile}`)
|
||||
console.log(`共生成 ${jsFiles.length} 个导入语句和 ${exportList.length} 个导出变量`)
|
||||
} catch (error) {
|
||||
console.error('生成 PB 导入导出代码时出错:', error.message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取 $root.X 形式的导出
|
||||
*/
|
||||
function extractRootExports(code) {
|
||||
const exports = []
|
||||
const rootExportRegex = /\$root\.([A-Za-z][A-Za-z0-9_]*)\s*=/g
|
||||
|
||||
let match
|
||||
while ((match = rootExportRegex.exec(code)) !== null) {
|
||||
exports.push(match[1])
|
||||
}
|
||||
|
||||
return exports
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取 enum 定义
|
||||
*/
|
||||
function extractEnumExports(code) {
|
||||
const exports = []
|
||||
const enumRegex = /@enum\s*{.*?}\s*\n\s*\*\s*@exports\s+([A-Za-z][A-Za-z0-9_]*)/g
|
||||
|
||||
let match
|
||||
while ((match = enumRegex.exec(code)) !== null) {
|
||||
exports.push(match[1])
|
||||
}
|
||||
|
||||
return exports
|
||||
}
|
||||
|
||||
// 示例用法
|
||||
generatePbImportsAndExports('../assets/scripts/pb', '../assets/scripts/network/pbExport.ts')
|
Loading…
x
Reference in New Issue
Block a user