| 162 | [sn: number]: { rs: (data: any) => void, rj: (err: any) => void } | undefined; |
| 163 | } = {}; |
| 164 | callApi<T extends keyof ServiceType['req']>(apiName: T, req: ServiceType['req'][T], options: TransportOptions = {}): SuperPromise<ServiceType['res'][T], TsrpcError> { |
| 165 | let sn = this._apiReqSnCounter.getNext(); |
| 166 | this.logger.log(`[ApiReq] #${sn}`, apiName, req); |
| 167 | |
| 168 | if (!this._ws) { |
| 169 | throw new Error('Not connected') |
| 170 | } |
| 171 | |
| 172 | // GetService |
| 173 | let service = this.serviceMap.apiName2Service[apiName as string]; |
| 174 | if (!service) { |
| 175 | throw new Error('Invalid api name: ' + apiName); |
| 176 | } |
| 177 | |
| 178 | // Encode |
| 179 | let buf = TransportDataUtil.encodeApiReq(this.tsbuffer, service, req, sn); |
| 180 | |
| 181 | // Wait Res |
| 182 | let promise = new SuperPromise<ServiceType['res'][T], TsrpcError>((rs, rj) => { |
| 183 | this._pendingApi[sn] = { |
| 184 | rs: rs, |
| 185 | rj: rj |
| 186 | } |
| 187 | }); |
| 188 | |
| 189 | // Send |
| 190 | this._ws.send(buf, err => { |
| 191 | if (err) { |
| 192 | this.logger.error('WebSocket Send Error:', err); |
| 193 | this._pendingApi[sn] && this._pendingApi[sn]!.rj(new TsrpcError('Network Error', { |
| 194 | code: (err as any).code, |
| 195 | isNetworkError: true, |
| 196 | innerError: err |
| 197 | })) |
| 198 | } |
| 199 | }); |
| 200 | |
| 201 | // onCancel |
| 202 | promise.onCancel(() => { |
| 203 | this.logger.log(`[ApiCancel] #${sn}`); |
| 204 | }) |
| 205 | |
| 206 | // Timeout |
| 207 | let timeout = options.timeout !== undefined ? options.timeout : this.options.timeout; |
| 208 | let timeoutTimer: ReturnType<typeof setTimeout> | undefined; |
| 209 | let clear = () => { |
| 210 | if (timeoutTimer) { |
| 211 | clearTimeout(timeoutTimer); |
| 212 | timeoutTimer = undefined; |
| 213 | } |
| 214 | if (this._pendingApi[sn]) { |
| 215 | delete this._pendingApi[sn]; |
| 216 | } |
| 217 | } |
| 218 | if (timeout > 0) { |
| 219 | timeoutTimer = setTimeout(() => { |
| 220 | if (this._pendingApi[sn]) { |
| 221 | this.logger.log(`[ApiTimeout] #${sn}`); |