490 lines
15 KiB
Vue
490 lines
15 KiB
Vue
<template>
|
|
<v-container>
|
|
<v-card>
|
|
<v-card-title>
|
|
协议测试
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<v-row justify="start">
|
|
<v-col cols="6">
|
|
<v-text-field v-model="ws_url"
|
|
label="服务端连接地址"
|
|
variant="outlined"
|
|
clearable
|
|
:error="error"
|
|
:error-messages="error_message"
|
|
:disabled="isconnect || connecting"
|
|
clear-icon="mdi-cancel"></v-text-field>
|
|
</v-col>
|
|
<v-col cols="3">
|
|
<v-btn flat
|
|
:loading="connecting"
|
|
@click="isconnect ? disconnect():connect()"
|
|
color="secondary">
|
|
{{isconnect ? '断开':'连接'}}
|
|
</v-btn>
|
|
</v-col>
|
|
</v-row>
|
|
<v-divider inset></v-divider>
|
|
<v-row class="mt-5">
|
|
<v-col cols="2">
|
|
<v-select v-model="mainSelect"
|
|
:items="proto_models"
|
|
item-title="mainType"
|
|
item-value="subs"
|
|
label="mainType"
|
|
:disabled="!isconnect"
|
|
@update:modelValue="mainSelectUpdate"
|
|
single-line
|
|
return-object></v-select>
|
|
</v-col>
|
|
<v-col cols="2">
|
|
<v-select v-model="subSelect"
|
|
:items="mainSelect.subs"
|
|
item-title="subType"
|
|
item-value="reqproto"
|
|
label="subType"
|
|
:disabled="!isconnect || mainSelect.disabled"
|
|
@update:modelValue="subSelectUpdate"
|
|
single-line
|
|
return-object></v-select>
|
|
</v-col>
|
|
</v-row>
|
|
<v-divider inset></v-divider>
|
|
<v-row v-if="reqproto.length > 0"
|
|
class="mt-5">
|
|
<v-col v-for="item in reqproto"
|
|
:key="item.FieldName"
|
|
cols="4">
|
|
|
|
<v-card>
|
|
<v-card-title>{{item.FieldName}}</v-card-title>
|
|
<v-card-text>
|
|
<v-text-field v-if="item.FieldType != 'Object'"
|
|
color="tertiary"
|
|
v-model="item.FieldValue"
|
|
:label="item.FieldName"
|
|
:type="item.FieldType"
|
|
:hint="item.FieldType"
|
|
:disabled="!isconnect"
|
|
outlined
|
|
clearable></v-text-field>
|
|
<Vue3JsonEditor v-else
|
|
v-model="item.FieldValue"
|
|
@json-change="(v)=>{item.FieldValue = v}"
|
|
:showBtns="false"
|
|
:mode="'code'"
|
|
lang="zh"
|
|
:expandedOnStart="false"></Vue3JsonEditor>
|
|
</v-card-text>
|
|
|
|
</v-card>
|
|
|
|
</v-col>
|
|
</v-row>
|
|
<v-row class="mt-5">
|
|
<v-col cols="3">
|
|
<v-btn flat
|
|
class="text-capitalize"
|
|
:disabled="subSelect == null"
|
|
@click="reqprotohandle"
|
|
color="secondary">
|
|
request
|
|
</v-btn>
|
|
</v-col>
|
|
</v-row>
|
|
</v-card-text>
|
|
</v-card>
|
|
<v-card class="mt-12">
|
|
<v-card-title>
|
|
<v-row justify="space-between">
|
|
<v-col>输出</v-col>
|
|
<v-col cols="auto">
|
|
<v-btn flat
|
|
prepend-icon="mdi-broom"
|
|
@click="logs=[]"
|
|
color="secondary">
|
|
Clear
|
|
</v-btn>
|
|
</v-col>
|
|
</v-row>
|
|
</v-card-title>
|
|
<v-divider></v-divider>
|
|
<v-responsive class="overflow-y-auto"
|
|
height="500">
|
|
<v-lazy :options="{threshold: .5}"
|
|
min-height="200"
|
|
transition="fade-transition">
|
|
|
|
<v-list>
|
|
<v-list-item v-for="log in logs"
|
|
:key="log">
|
|
<v-alert :type="log.type"
|
|
variant="outlined"
|
|
:title="log.title">
|
|
<template v-if="log.data"
|
|
v-slot:append>
|
|
<v-list-item-avatar end>
|
|
<v-btn variant="text"
|
|
size="x-large"
|
|
@click="log.isshow = !log.isshow"
|
|
:icon="log.isshow ? 'mdi-chevron-left':'mdi-chevron-down'"></v-btn>
|
|
</v-list-item-avatar>
|
|
</template>
|
|
<div v-if="log.data"
|
|
v-show="log.isshow">
|
|
<v-divider></v-divider>
|
|
<pre>{{log.data}}</pre>
|
|
</div>
|
|
</v-alert>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-lazy>
|
|
</v-responsive>
|
|
</v-card>
|
|
<v-snackbar v-model="error">
|
|
{{ error_message }}
|
|
<template v-slot:actions>
|
|
<v-btn color="pink"
|
|
variant="text"
|
|
@click="error = false">
|
|
Close
|
|
</v-btn>
|
|
</template>
|
|
</v-snackbar>
|
|
</v-container>
|
|
</template>
|
|
|
|
<script>
|
|
import { Base64 } from 'js-base64'
|
|
import md5 from 'js-md5'
|
|
import { reactive } from 'vue'
|
|
import proto from '@/pb/proto'
|
|
import { socket } from '@/utils/socket'
|
|
import { Vue3JsonEditor } from 'vue3-json-editor'
|
|
import { defineComponent } from 'vue'
|
|
|
|
export default defineComponent({
|
|
name: 'Protocol',
|
|
components: { Vue3JsonEditor },
|
|
data() {
|
|
return {
|
|
ws_url: 'ws://localhost:7891/gateway',
|
|
isconnect: false,
|
|
connecting: false,
|
|
error: false,
|
|
error_message: '',
|
|
proto_models: null,
|
|
mainSelect: { protoName: '', mainType: 'User', subs: [] },
|
|
subSelect: null,
|
|
reqproto: [],
|
|
reqloading: false,
|
|
islogin: false,
|
|
account: '',
|
|
serverId: 0,
|
|
logs: [],
|
|
isshow: true,
|
|
showdata: { name: 'liwei1dao', aog: 123 },
|
|
resultInfo: { li: 123 },
|
|
}
|
|
},
|
|
computed: {},
|
|
setup() {
|
|
const proto_models = reactive([
|
|
{ mainType: 'notify', disabled: true, subs: [] },
|
|
{ mainType: 'user', subs: [] },
|
|
{ mainType: 'items', subs: [] },
|
|
{ mainType: 'mail', subs: [] },
|
|
{ mainType: 'friend', subs: [] },
|
|
{ mainType: 'equipment', subs: [] },
|
|
{ mainType: 'hero', subs: [] },
|
|
])
|
|
for (const v of Object.keys(proto)) {
|
|
for (const v1 of proto_models) {
|
|
// console.log('protoName', v)
|
|
let protoName = v.toLowerCase()
|
|
//找到模块的消息对象
|
|
let index = protoName.indexOf(v1.mainType)
|
|
if (index == 0) {
|
|
let reqindex = protoName.indexOf('req')
|
|
let respindex = protoName.indexOf('resp')
|
|
let pushindex = protoName.indexOf('push')
|
|
if (reqindex != -1) {
|
|
let sub = protoName.substring(index + v1.mainType.length, reqindex)
|
|
let iskeep = false
|
|
for (const v2 of v1.subs) {
|
|
if (v2.subType == sub) {
|
|
v2.reqproto = proto[v]
|
|
iskeep = true
|
|
break
|
|
}
|
|
}
|
|
if (!iskeep) {
|
|
v1.subs.push({
|
|
reqName: v,
|
|
mainType: v1.mainType,
|
|
subType: sub,
|
|
reqproto: proto[v],
|
|
})
|
|
// console.log(sub + 'Req')
|
|
}
|
|
}
|
|
if (respindex != -1) {
|
|
let sub = protoName.substring(index + v1.mainType.length, respindex)
|
|
let iskeep = false
|
|
for (const v2 of v1.subs) {
|
|
if (v2.subType == sub) {
|
|
v2.respName = v
|
|
v2.respproto = proto[v]
|
|
iskeep = true
|
|
break
|
|
}
|
|
}
|
|
if (!iskeep) {
|
|
v1.subs.push({
|
|
respName: v,
|
|
mainType: v1.mainType,
|
|
subType: sub,
|
|
respproto: proto[v],
|
|
})
|
|
// console.log(sub + 'Resp')
|
|
}
|
|
}
|
|
if (pushindex != -1) {
|
|
let sub = protoName.substring(index + v1.mainType.length, pushindex)
|
|
let iskeep = false
|
|
for (const v2 of v1.subs) {
|
|
if (v2.subType == sub) {
|
|
v2.pushName = v
|
|
v2.pushproto = proto[v]
|
|
iskeep = true
|
|
break
|
|
}
|
|
}
|
|
if (!iskeep) {
|
|
v1.subs.push({
|
|
pushName: v,
|
|
mainType: v1.mainType,
|
|
subType: sub,
|
|
pushproto: proto[v],
|
|
})
|
|
// console.log(sub + 'Resp')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return { proto_models }
|
|
},
|
|
onBeforeUnmount() {
|
|
// 关闭连接
|
|
socket.close()
|
|
},
|
|
methods: {
|
|
connect() {
|
|
// 发起连接
|
|
this.connecting = true
|
|
socket.receivelisten = this.receivelisten
|
|
|
|
socket
|
|
.init(this.ws_url)
|
|
.then((value) => {
|
|
this.error = false
|
|
this.error_message = ''
|
|
this.isconnect = true
|
|
this.connecting = false
|
|
this.pushlog('success', `连接创建成功`)
|
|
socket.closelisten = this.closelisten
|
|
})
|
|
.catch((error) => {
|
|
this.error = true
|
|
this.error_message = error
|
|
this.isconnect = false
|
|
this.connecting = false
|
|
this.subSelect = null
|
|
this.reqproto = []
|
|
this.pushlog('error', `连接创建失败:${this.ws_url}`)
|
|
})
|
|
},
|
|
disconnect() {
|
|
socket.close()
|
|
this.isconnect = false
|
|
this.subSelect = null
|
|
this.reqproto = []
|
|
},
|
|
mainSelectUpdate(v) {
|
|
console.log(v)
|
|
this.subSelect = null
|
|
this.reqproto = []
|
|
},
|
|
subSelectUpdate(v) {
|
|
this.reqproto = []
|
|
let keys = Object.keys(this.subSelect.reqproto.fields)
|
|
for (const v of keys) {
|
|
let ftype = this.subSelect.reqproto.fields[v].type
|
|
console.log('ftype', ftype)
|
|
let fvalue = null
|
|
switch (this.subSelect.reqproto.fields[v].type) {
|
|
case 'int32':
|
|
case 'int64':
|
|
case 'uint32':
|
|
case 'uint64':
|
|
case 'float32':
|
|
case 'float64':
|
|
ftype = 'number'
|
|
fvalue = 0
|
|
break
|
|
case 'string':
|
|
ftype = 'text'
|
|
fvalue = ''
|
|
break
|
|
default:
|
|
ftype = 'Object'
|
|
fvalue = {}
|
|
break
|
|
}
|
|
|
|
this.reqproto.push({
|
|
FieldName: v,
|
|
FieldType: ftype,
|
|
FieldValue: fvalue,
|
|
})
|
|
}
|
|
console.log(this.reqproto)
|
|
},
|
|
closelisten() {
|
|
this.isconnect = false
|
|
this.subSelect = null
|
|
this.reqproto = []
|
|
console.log('closelisten!')
|
|
this.pushlog('error', `连接断开${this.ws_url}`)
|
|
},
|
|
//接收服务的消息
|
|
receivelisten(msg) {
|
|
// console.log('接收到消息', msg.data.arrayBuffer())
|
|
msg.data
|
|
.arrayBuffer()
|
|
.then((buf) => new Uint8Array(buf))
|
|
.then((bytes) => {
|
|
console.log('bytes', bytes)
|
|
let message = proto.lookup('UserMessage').decode(bytes)
|
|
console.log('接收到消息 message', message)
|
|
let mainType = message.MainType
|
|
let subType = message.SubType
|
|
let iskeep = false
|
|
for (const v of this.proto_models) {
|
|
if (v.mainType == mainType) {
|
|
for (const v1 of v.subs) {
|
|
if (subType == v1.subType) {
|
|
console.log('接收到消息 v1', v1)
|
|
//找到消息组
|
|
iskeep = true
|
|
let protoobj = null
|
|
let messageobj = null
|
|
if (v1.respName) {
|
|
console.log('接收到消息 respName', v1.respName)
|
|
protoobj = proto
|
|
.lookup(v1.respName)
|
|
.decode(message.data.value)
|
|
messageobj = proto.lookup(v1.respName).toObject(protoobj)
|
|
// console.log('接收回应到消息 protoobj', protoobj)
|
|
} else {
|
|
console.log('接收到消息 pushName', v1.pushName)
|
|
protoobj = proto
|
|
.lookup(v1.pushName)
|
|
.decode(message.data.value)
|
|
messageobj = proto.lookup(v1.pushName).toObject(protoobj)
|
|
}
|
|
if (v1.pushName && v1.pushName == 'NotifyErrorNotifyPush') {
|
|
this.pushlog(
|
|
'error',
|
|
`错误信息通知: ${mainType}-${subType}-resp`,
|
|
messageobj
|
|
)
|
|
} else {
|
|
this.pushlog(
|
|
'success',
|
|
`收到回应消息: ${mainType}-${subType}-resp`,
|
|
messageobj
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (iskeep) {
|
|
break
|
|
}
|
|
}
|
|
if (!iskeep) {
|
|
this.pushlog(
|
|
'error',
|
|
`接收消息错误 ${mainType}-${subType}`,
|
|
'未找到指定消息对象'
|
|
)
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.log('接收到消息异常', error)
|
|
this.pushlog('error', '接收消息异常', { msg: msg, e: e })
|
|
})
|
|
},
|
|
//请求消息
|
|
reqprotohandle() {
|
|
console.log('protoName:', this.subSelect.reqName)
|
|
let protoobj = proto.lookup(this.subSelect.reqName)
|
|
for (const v of this.reqproto) {
|
|
protoobj[v.FieldName] = v.FieldValue
|
|
}
|
|
let message = proto.lookup('UserMessage')
|
|
let any = proto.lookup('google.protobuf.Any')
|
|
message.MainType = this.subSelect.mainType
|
|
message.SubType = this.subSelect.subType
|
|
message.data = any.create({
|
|
type_url: `type.googleapis.com/${this.subSelect.reqName}`,
|
|
value: proto.lookup(this.subSelect.reqName).encode(protoobj).finish(), // Or as packed buffer
|
|
})
|
|
if (this.subSelect.reqName == 'UserLoginReq') {
|
|
//登录协议特殊处理
|
|
message.sec = this.buildsecStr(protoobj.account, protoobj.sid)
|
|
} else {
|
|
message.sec = this.buildsecStr()
|
|
}
|
|
console.log('message:', message)
|
|
let buffer = proto.lookup('UserMessage').encode(message).finish()
|
|
console.log('req buff:', buffer)
|
|
socket.send(buffer)
|
|
this.pushlog(
|
|
'success',
|
|
`发送请求消息: ${message.MainType}-${message.SubType}-req`,
|
|
proto.lookup(this.subSelect.reqName).toObject(protoobj)
|
|
)
|
|
},
|
|
buildsecStr(_account, _serverId) {
|
|
_account = _account ? _account : this.account
|
|
_serverId = _serverId ? _serverId : this.serverId
|
|
let jsonStr = JSON.stringify({
|
|
account: _account,
|
|
serverId: _serverId,
|
|
timestamp: Date.parse(new Date()) / 1000,
|
|
})
|
|
let baseStr = Base64.encode(jsonStr)
|
|
let clientMd5key = md5(baseStr)
|
|
console.log('clientMd5key:', clientMd5key)
|
|
return `CE:${clientMd5key}${baseStr}`
|
|
},
|
|
pushlog(_type, _title, _data) {
|
|
this.logs.push({
|
|
type: _type,
|
|
title: _title,
|
|
data: _data,
|
|
isshow: false,
|
|
})
|
|
},
|
|
|
|
onJsonChange(value) {
|
|
console.log('value:', value)
|
|
},
|
|
},
|
|
})
|
|
</script>
|