Compare commits
3 Commits
96e0ac9782
...
f0de649733
Author | SHA1 | Date | |
---|---|---|---|
f0de649733 | |||
c2901b2e37 | |||
787ac75484 |
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
2. 登陆界面
|
2. 登陆界面
|
||||||
1. 连接网关并实现登陆功能。(已完成)
|
1. 连接网关并实现登陆功能。(已完成)
|
||||||
2. 编写单独的消息解码器,派发消息时是已解码的消息。
|
2. 编写单独的消息解码器,派发消息时是已解码的消息。(已完成)
|
||||||
3. 登陆成功后关闭登陆界面,进入大厅界面。
|
3. 登陆成功后关闭登陆界面,进入大厅界面。
|
||||||
4. 网络断开时弹出转圈圈界面。
|
4. 网络断开时弹出转圈圈界面。
|
||||||
|
5. ai 生成更宽一点的登陆界面,以及登陆注册 ui,转圈圈图标。
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { _decorator, Button, Component, EditBox, Label, Node } from 'cc'
|
import { _decorator, Button, Component, EditBox, Label, Node } from 'cc'
|
||||||
import { WsClient } from '../network/wsclient'
|
import { WsClient } from '../network/wsclient'
|
||||||
import { WsConfig } from '../network/wsconfig'
|
import { WsConfig } from '../network/wsconfig'
|
||||||
import { PbHelper } from '../network/pbHelper'
|
import * as pb from '../network/pbExport'
|
||||||
import { ReqUserLogin, ServiceTypeId, MsgId, RspUserLogin } from '../network/pbExport'
|
import { MessageDispatcher } from '../network/messageDispatcher'
|
||||||
import { EventType } from '../constant'
|
|
||||||
const { ccclass, property } = _decorator
|
const { ccclass, property } = _decorator
|
||||||
|
|
||||||
@ccclass('loginPanel')
|
@ccclass('loginPanel')
|
||||||
@ -21,11 +20,11 @@ export class loginPanel extends Component {
|
|||||||
start() {
|
start() {
|
||||||
this.loginButton.node.on(Button.EventType.CLICK, this.onLoginButtonClick, this)
|
this.loginButton.node.on(Button.EventType.CLICK, this.onLoginButtonClick, this)
|
||||||
// 监听websocket消息事件
|
// 监听websocket消息事件
|
||||||
window.addEventListener(EventType.Ws, this.onMessage.bind(this))
|
MessageDispatcher.Instance.On(pb.MsgId.RspUserLoginId, this.onLogin.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onDestroy(): void {
|
protected onDestroy(): void {
|
||||||
window.removeEventListener(EventType.Ws, this.onMessage.bind(this))
|
MessageDispatcher.Instance.Off(pb.MsgId.RspUserLoginId, this.onLogin.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录按钮点击处理函数
|
// 登录按钮点击处理函数
|
||||||
@ -40,40 +39,30 @@ export class loginPanel extends Component {
|
|||||||
this.statusLable.string = '请输入密码'
|
this.statusLable.string = '请输入密码'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const ws = WsClient.Instance()
|
const ws = WsClient.Instance
|
||||||
console.log(typeof ws)
|
console.log(typeof ws)
|
||||||
if (!ws.IsConnected) {
|
if (!WsClient.Instance.IsConnected) {
|
||||||
await ws.ConnectAsync(WsConfig.Address[1].Address[0])
|
await WsClient.Instance.ConnectAsync(WsConfig.Address[1].Address[0])
|
||||||
if (!ws.IsConnected) {
|
if (!WsClient.Instance.IsConnected) {
|
||||||
this.statusLable.string = '连接网络失败'
|
this.statusLable.string = '连接网络失败'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// console.log('登陆帐号:', username, '密码:', pwd)
|
||||||
console.log('登陆帐号:', username, '密码:', pwd)
|
this.reqLogin(username, pwd)
|
||||||
|
|
||||||
const req = new ReqUserLogin()
|
|
||||||
req.username = username
|
|
||||||
req.password = pwd
|
|
||||||
req.version = '20250601123030'
|
|
||||||
const buffer = ReqUserLogin.encode(req).finish()
|
|
||||||
ws.Send(ServiceTypeId.STI_Login, MsgId.ReqUserLoginId, buffer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMessage(event: CustomEvent) {
|
private reqLogin(username, password: string) {
|
||||||
try {
|
const req = new pb.ReqUserLogin()
|
||||||
const [msgid, buffer] = PbHelper.DecodeClient(event.detail)
|
req.username = username
|
||||||
switch (msgid) {
|
req.password = password
|
||||||
case MsgId.RspUserLoginId:
|
req.version = '20250601123030'
|
||||||
const rsp = PbHelper.Decode(RspUserLogin, buffer)
|
const buffer = pb.ReqUserLogin.encode(req).finish()
|
||||||
console.log('收到返回消息:', rsp)
|
WsClient.Instance.Send(pb.ServiceTypeId.STI_Login, pb.MsgId.ReqUserLoginId, buffer)
|
||||||
default:
|
}
|
||||||
// console.log('收到非json消息:', event.detail)
|
|
||||||
}
|
private onLogin(rsp: typeof pb.RspUserLogin.prototype) {
|
||||||
} catch (error) {
|
console.log('收到返回消息:', rsp)
|
||||||
// console.log('解析错误失败:', error)
|
|
||||||
console.log(PbHelper.Uint8ToHex(event.detail))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update(deltaTime: number) {}
|
update(deltaTime: number) {}
|
||||||
|
50
assets/scripts/network/messageDecoder.ts
Normal file
50
assets/scripts/network/messageDecoder.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// MessageDecoder.ts
|
||||||
|
import * as pb from './pbExport'
|
||||||
|
|
||||||
|
export class MessageDecoder {
|
||||||
|
// 消息ID与消息类的映射表
|
||||||
|
private static _messageClasses: Map<number, (buffer: Uint8Array) => any> = new Map()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册消息类(启动时调用)
|
||||||
|
* @param msgId 消息ID
|
||||||
|
* @param decoder 解码函数(如 pb.ReqUserLogin.decode)
|
||||||
|
*/
|
||||||
|
public static Register<T>(msgId: number, decoder: (buffer: Uint8Array) => T): void {
|
||||||
|
this._messageClasses.set(msgId, decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解码消息(根据ID动态实例化对应消息类)
|
||||||
|
* @param msgId 消息ID
|
||||||
|
* @param buffer 原始消息(Uint8Array)
|
||||||
|
* @returns 解码后的消息对象
|
||||||
|
*/
|
||||||
|
public static Decode(msgId: number, buffer: Uint8Array): [any, Error] {
|
||||||
|
try {
|
||||||
|
const decoder = this._messageClasses.get(msgId)
|
||||||
|
if (!decoder) {
|
||||||
|
return [null, new Error(`未注册的消息ID: ${msgId}`)]
|
||||||
|
}
|
||||||
|
// 实例化消息类并解码数据
|
||||||
|
const instance = decoder(buffer)
|
||||||
|
return [instance, null]
|
||||||
|
} catch (err) {
|
||||||
|
return [null, new Error(`解消息: ${msgId} 失败。err:${err}`)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字节流转换成Hex码
|
||||||
|
* @param buffer 原始消息(Uint8Array)
|
||||||
|
* @returns 字节流转换成Hex码
|
||||||
|
*/
|
||||||
|
public static Uint8ToHex(buffer: Uint8Array): string {
|
||||||
|
return Array.from(buffer)
|
||||||
|
.map((byte) => byte.toString(16).padStart(2, '0'))
|
||||||
|
.join(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDecoder.Register(pb.MsgId.ReqUserLoginId, pb.ReqUserLogin.decode)
|
||||||
|
MessageDecoder.Register(pb.MsgId.RspUserLoginId, pb.RspUserLogin.decode)
|
71
assets/scripts/network/messageDispatcher.ts
Normal file
71
assets/scripts/network/messageDispatcher.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// MessageDispatcher.ts
|
||||||
|
|
||||||
|
/** 消息处理器类型 */
|
||||||
|
export type MessageHandler = (data: any) => void
|
||||||
|
|
||||||
|
export class MessageDispatcher {
|
||||||
|
private static _instance: MessageDispatcher
|
||||||
|
private _handlers: Map<number, MessageHandler[]> = new Map()
|
||||||
|
|
||||||
|
/** 单例模式 */
|
||||||
|
public static get Instance(): MessageDispatcher {
|
||||||
|
if (!this._instance) {
|
||||||
|
this._instance = new MessageDispatcher()
|
||||||
|
}
|
||||||
|
return this._instance
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册消息处理器(允许多个 Handler)
|
||||||
|
* @param msgId 消息ID
|
||||||
|
* @param handler 回调函数
|
||||||
|
*/
|
||||||
|
public On(msgId: number, handler: MessageHandler): void {
|
||||||
|
if (!this._handlers.has(msgId)) {
|
||||||
|
this._handlers.set(msgId, [])
|
||||||
|
}
|
||||||
|
this._handlers.get(msgId)?.push(handler) // 添加到队列
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除指定的消息处理器(通过函数引用精准匹配)
|
||||||
|
* @param msgId 消息ID
|
||||||
|
* @param handler 要移除的回调函数
|
||||||
|
*/
|
||||||
|
public Off(msgId: number, handler: MessageHandler): void {
|
||||||
|
const handlers = this._handlers.get(msgId)
|
||||||
|
if (!handlers) return
|
||||||
|
|
||||||
|
// 过滤掉指定的 handler
|
||||||
|
const newHandlers = handlers.filter((h) => h !== handler)
|
||||||
|
this._handlers.set(msgId, newHandlers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息派发器中handler数量
|
||||||
|
* @param msgId 消息ID
|
||||||
|
* @returns 返回消息派发器中handler数量
|
||||||
|
*/
|
||||||
|
public Size(msgId: number): number {
|
||||||
|
if (msgId === 0) {
|
||||||
|
return this._handlers.size
|
||||||
|
}
|
||||||
|
const handlers = this._handlers.get(msgId)
|
||||||
|
if (handlers) {
|
||||||
|
return handlers.length
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派发消息(按注册顺序执行所有 Handler)
|
||||||
|
* @param msgId 消息ID
|
||||||
|
* @param msg 消息数据
|
||||||
|
*/
|
||||||
|
public Dispatch(msgId: number, msg: any): void {
|
||||||
|
const handlers = this._handlers.get(msgId)
|
||||||
|
if (handlers) {
|
||||||
|
handlers.forEach((handler) => handler(msg)) // 顺序执行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { ClientMsg } from '../network/pbExport'
|
import { ClientMsg } from '../network/pbExport'
|
||||||
import { EventType } from '../constant'
|
import { MessageDispatcher } from '../network/messageDispatcher'
|
||||||
import { PbHelper } from '../network/pbHelper'
|
import { MessageDecoder } from '../network/messageDecoder'
|
||||||
|
|
||||||
export class WsClient {
|
export class WsClient {
|
||||||
private socket: WebSocket | null = null
|
private socket: WebSocket | null = null
|
||||||
@ -11,13 +11,20 @@ export class WsClient {
|
|||||||
private isConnected: boolean = false
|
private isConnected: boolean = false
|
||||||
|
|
||||||
private static instance: WsClient = null
|
private static instance: WsClient = null
|
||||||
|
private static netEvent: EventTarget = null
|
||||||
|
|
||||||
// 单例
|
// 单例
|
||||||
public static Instance(): WsClient {
|
public static get Instance(): WsClient {
|
||||||
if (!this.instance) this.instance = new WsClient()
|
if (!this.instance) this.instance = new WsClient()
|
||||||
return this.instance
|
return this.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 网络事件中心
|
||||||
|
public static EventMgr(): EventTarget {
|
||||||
|
if (!this.netEvent) this.netEvent = new EventTarget()
|
||||||
|
return this.netEvent
|
||||||
|
}
|
||||||
|
|
||||||
// 是否连接
|
// 是否连接
|
||||||
public get IsConnected(): boolean {
|
public get IsConnected(): boolean {
|
||||||
return this.isConnected
|
return this.isConnected
|
||||||
@ -112,8 +119,14 @@ export class WsClient {
|
|||||||
const buffer = await event.data.arrayBuffer()
|
const buffer = await event.data.arrayBuffer()
|
||||||
const uint8Array = new Uint8Array(buffer)
|
const uint8Array = new Uint8Array(buffer)
|
||||||
// console.log('收到消息:', uint8Array)
|
// console.log('收到消息:', uint8Array)
|
||||||
console.log('收到消息:', PbHelper.Uint8ToHex(uint8Array))
|
const cMsg = ClientMsg.decode(uint8Array)
|
||||||
window.dispatchEvent(new CustomEvent(EventType.Ws, { detail: uint8Array }))
|
// console.log('收到消息:', MessageDecoder.Uint8ToHex(uint8Array))
|
||||||
|
const [msg, err] = MessageDecoder.Decode(cMsg.msgId, cMsg.data)
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
MessageDispatcher.Instance.Dispatch(cMsg.msgId, msg)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('解析网络消息失败:', error)
|
console.error('解析网络消息失败:', error)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user