зеркало из https://github.com/microsoft/jacdac-ts.git
fix: updated cloud adapter server
This commit is contained in:
Родитель
97b95358ac
Коммит
7095219bd4
|
@ -1 +1 @@
|
|||
Subproject commit 7ccd0b2461a2dae261b387de42a2683eeb44c3b5
|
||||
Subproject commit 4edbe62754ccf5415f8af9ec25bb0bae315d8e11
|
|
@ -1,50 +1,30 @@
|
|||
import {
|
||||
TIMEOUT,
|
||||
DEVICE_CHANGE,
|
||||
DISCONNECT,
|
||||
CloudAdapterCmd,
|
||||
CloudAdapterCommandStatus,
|
||||
CloudAdapterEvent,
|
||||
CloudAdapterReg,
|
||||
SELF_ANNOUNCE,
|
||||
SRV_CLOUD_ADAPTER,
|
||||
CHANGE,
|
||||
CloudAdapterCmdPack,
|
||||
} from "../jdom/constants"
|
||||
import { jdpack } from "../jdom/pack"
|
||||
import { Packet } from "../jdom/packet"
|
||||
import { JDRegisterServer } from "../jdom/servers/registerserver"
|
||||
import { JDServerOptions, JDServiceServer } from "../jdom/servers/serviceserver"
|
||||
|
||||
export const UPLOAD = "upload"
|
||||
export const UPLOAD_JSON = "upload"
|
||||
export const UPLOAD_BIN = "uploadBin"
|
||||
export const CLOUD_COMMAND = "cloudCommand"
|
||||
|
||||
export interface CloudAdapterUploadRequest {
|
||||
label: string
|
||||
args: number[]
|
||||
export interface CloudAdapterUploadJSONRequest {
|
||||
json: string
|
||||
}
|
||||
|
||||
export interface CloudAdapterUploadBinRequest {
|
||||
data: Uint8Array
|
||||
}
|
||||
|
||||
export interface CloudAdapterCommandResponse {
|
||||
status: CloudAdapterCommandStatus
|
||||
args: number[]
|
||||
}
|
||||
|
||||
export class CloudAdapterServer extends JDServiceServer {
|
||||
readonly connectedRegister: JDRegisterServer<[boolean]>
|
||||
readonly connectionNameRegister: JDRegisterServer<[string]>
|
||||
private seqNo = 0
|
||||
private pending: Record<
|
||||
string,
|
||||
{
|
||||
timeout: number
|
||||
resolve: (resp: CloudAdapterCommandResponse) => void
|
||||
reject: (reason?: unknown) => void
|
||||
}
|
||||
> = {}
|
||||
readonly controlled: boolean
|
||||
|
||||
constructor(
|
||||
|
@ -63,17 +43,14 @@ export class CloudAdapterServer extends JDServiceServer {
|
|||
CloudAdapterReg.ConnectionName,
|
||||
[options?.connectionName || ""]
|
||||
)
|
||||
this.addCommand(CloudAdapterCmd.Upload, this.handleUpload.bind(this))
|
||||
this.addCommand(
|
||||
CloudAdapterCmd.UploadBin,
|
||||
CloudAdapterCmd.UploadJson,
|
||||
this.handleUpload.bind(this)
|
||||
)
|
||||
this.addCommand(
|
||||
CloudAdapterCmd.UploadBinary,
|
||||
this.handleUploadBin.bind(this)
|
||||
)
|
||||
this.addCommand(
|
||||
CloudAdapterCmd.AckCloudCommand,
|
||||
this.handleAckCloudCommand.bind(this)
|
||||
)
|
||||
this.on(DEVICE_CHANGE, this.handleDeviceChange.bind(this))
|
||||
|
||||
this.connectedRegister.on(CHANGE, () =>
|
||||
this.sendEvent(CloudAdapterEvent.Change)
|
||||
)
|
||||
|
@ -82,13 +59,6 @@ export class CloudAdapterServer extends JDServiceServer {
|
|||
)
|
||||
}
|
||||
|
||||
private handleDeviceChange() {
|
||||
if (this.device) {
|
||||
this.device.on(DISCONNECT, this.clearPending.bind(this))
|
||||
this.device.on(SELF_ANNOUNCE, this.gcPending.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
get connected() {
|
||||
return this.connectedRegister.values()[0]
|
||||
}
|
||||
|
@ -106,8 +76,8 @@ export class CloudAdapterServer extends JDServiceServer {
|
|||
return
|
||||
}
|
||||
|
||||
const [label, args] = pkt.jdunpack<[string, number[]]>("z f64[]")
|
||||
this.upload(label, args)
|
||||
const [json] = pkt.jdunpack<[string]>(CloudAdapterCmdPack.UploadJson)
|
||||
this.uploadJSON(json)
|
||||
}
|
||||
|
||||
private async handleUploadBin(pkt: Packet) {
|
||||
|
@ -120,74 +90,13 @@ export class CloudAdapterServer extends JDServiceServer {
|
|||
this.uploadBin(data)
|
||||
}
|
||||
|
||||
upload(label: string, args: number[]) {
|
||||
//console.log("cloud: upload", { label, args })
|
||||
this.emit(UPLOAD, <CloudAdapterUploadRequest>{ label, args })
|
||||
}
|
||||
|
||||
uploadBin(data: Uint8Array) {
|
||||
//console.log("cloud: upload bin", { data })
|
||||
this.emit(UPLOAD_BIN, <CloudAdapterUploadBinRequest>{ data })
|
||||
}
|
||||
|
||||
sendCloudCommand(
|
||||
method: string,
|
||||
args: number[],
|
||||
timeout = 1000
|
||||
): Promise<CloudAdapterCommandResponse> {
|
||||
if (!this.connected) {
|
||||
console.debug(`cloud: cancel send, not connected`)
|
||||
return
|
||||
}
|
||||
const seqNo = this.seqNo++
|
||||
const payload = jdpack<[number, string, [number][]]>("u32 z r: f64", [
|
||||
seqNo,
|
||||
method,
|
||||
args.map(v => [v]),
|
||||
])
|
||||
return new Promise<CloudAdapterCommandResponse>((resolve, reject) => {
|
||||
console.log(
|
||||
`cloud: send ${seqNo} (${Object.keys(seqNo).length} pending)`
|
||||
)
|
||||
this.pending[seqNo] = {
|
||||
timeout: this.device.bus.timestamp + timeout,
|
||||
resolve,
|
||||
reject,
|
||||
}
|
||||
this.sendEvent(CloudAdapterEvent.CloudCommand, payload)
|
||||
uploadJSON(json: string) {
|
||||
this.emit(UPLOAD_JSON, <CloudAdapterUploadJSONRequest>{
|
||||
json,
|
||||
})
|
||||
}
|
||||
|
||||
private async handleAckCloudCommand(pkt: Packet) {
|
||||
const [seqNo, status, args] =
|
||||
pkt.jdunpack<[number, CloudAdapterCommandStatus, number[]]>(
|
||||
"u32 u32 f64[]"
|
||||
)
|
||||
console.log("cloud: ack-invoke", seqNo, status, args)
|
||||
const resp = { status, args }
|
||||
const req = this.pending[seqNo]
|
||||
if (req) {
|
||||
delete this.pending[seqNo]
|
||||
req.resolve(resp)
|
||||
}
|
||||
}
|
||||
|
||||
private gcPending() {
|
||||
const now = this.device.bus.timestamp
|
||||
Object.entries(this.pending)
|
||||
.filter(([, req]) => req.timeout > now)
|
||||
.map(([key]) => {
|
||||
const reject = this.pending[key]?.reject
|
||||
delete this.pending[key]
|
||||
return reject
|
||||
})
|
||||
.filter(r => !!r)
|
||||
.forEach(r => r(TIMEOUT))
|
||||
}
|
||||
|
||||
private clearPending() {
|
||||
const p = this.pending
|
||||
this.pending = {}
|
||||
Object.values(p).forEach(({ reject }) => reject())
|
||||
uploadBin(data: Uint8Array) {
|
||||
this.emit(UPLOAD_BIN, <CloudAdapterUploadBinRequest>{ data })
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче