Handle serializers asynchronously (!428)
In combination with my other PR handle all the serializers asynchronously too, this should almost result in a fully asynchronous sending of responses. Reviewed-on: https://dev.sp-tarkov.com/SPT/Server/pulls/428 Co-authored-by: Archangel <jesse@archangel.wtf> Co-committed-by: Archangel <jesse@archangel.wtf>
This commit is contained in:
parent
9f8fbd181f
commit
b841addd78
@ -1,7 +1,7 @@
|
||||
import { IncomingMessage, ServerResponse } from "node:http";
|
||||
|
||||
export class Serializer {
|
||||
public serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void {
|
||||
public async serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise<void> {
|
||||
throw new Error("Should be extended and overrode");
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,13 @@ export class ImageRouter {
|
||||
this.imageRouteService.addRoute(key, valueToAdd);
|
||||
}
|
||||
|
||||
public sendImage(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void {
|
||||
public async sendImage(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise<void> {
|
||||
// remove file extension
|
||||
const url = this.vfs.stripExtension(req.url);
|
||||
|
||||
// send image
|
||||
if (this.imageRouteService.existsByKey(url)) {
|
||||
this.httpFileUtil.sendFile(resp, this.imageRouteService.getByKey(url));
|
||||
await this.httpFileUtil.sendFileAsync(resp, this.imageRouteService.getByKey(url));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ export class BundleSerializer extends Serializer {
|
||||
super();
|
||||
}
|
||||
|
||||
public override serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void {
|
||||
public override async serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise<void> {
|
||||
const key = decodeURI(req.url.split("/bundle/")[1]);
|
||||
const bundle = this.bundleLoader.getBundle(key);
|
||||
if (!bundle) {
|
||||
@ -29,7 +29,7 @@ export class BundleSerializer extends Serializer {
|
||||
return;
|
||||
}
|
||||
|
||||
this.httpFileUtil.sendFile(resp, `${bundle.modpath}/bundles/${bundle.filename}`);
|
||||
await this.httpFileUtil.sendFileAsync(resp, `${bundle.modpath}/bundles/${bundle.filename}`);
|
||||
}
|
||||
|
||||
public override canHandle(route: string): boolean {
|
||||
|
@ -9,8 +9,8 @@ export class ImageSerializer extends Serializer {
|
||||
super();
|
||||
}
|
||||
|
||||
public override serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void {
|
||||
this.imageRouter.sendImage(sessionID, req, resp, body);
|
||||
public override async serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise<void> {
|
||||
await this.imageRouter.sendImage(sessionID, req, resp, body);
|
||||
}
|
||||
|
||||
public override canHandle(route: string): boolean {
|
||||
|
@ -15,7 +15,7 @@ export class NotifySerializer extends Serializer {
|
||||
super();
|
||||
}
|
||||
|
||||
public override serialize(_sessionID: string, req: IncomingMessage, resp: ServerResponse, _: any): void {
|
||||
public override async serialize(_sessionID: string, req: IncomingMessage, resp: ServerResponse, _: any): Promise<void> {
|
||||
const splittedUrl = req.url.split("/");
|
||||
const tmpSessionID = splittedUrl[splittedUrl.length - 1].split("?last_id")[0];
|
||||
|
||||
@ -23,7 +23,7 @@ export class NotifySerializer extends Serializer {
|
||||
* Take our array of JSON message objects and cast them to JSON strings, so that they can then
|
||||
* be sent to client as NEWLINE separated strings... yup.
|
||||
*/
|
||||
this.notifierController
|
||||
await this.notifierController
|
||||
.notifyAsync(tmpSessionID)
|
||||
.then((messages: any) => messages.map((message: any) => this.jsonUtil.serialize(message)).join("\n"))
|
||||
.then((text) => this.httpServerHelper.sendTextJson(resp, text));
|
||||
|
@ -107,7 +107,7 @@ export class SptHttpListener implements IHttpListener {
|
||||
// Not debug, minority of requests need a serializer to do the job (IMAGE/BUNDLE/NOTIFY)
|
||||
const serialiser = this.serializers.find((x) => x.canHandle(output));
|
||||
if (serialiser) {
|
||||
serialiser.serialize(sessionID, req, resp, bodyInfo);
|
||||
await serialiser.serialize(sessionID, req, resp, bodyInfo);
|
||||
} else {
|
||||
// No serializer can handle the request (majority of requests dont), zlib the output and send response back
|
||||
await this.sendZlibJson(resp, output, sessionID);
|
||||
|
@ -2,21 +2,20 @@ import fs from "node:fs";
|
||||
import { ServerResponse } from "node:http";
|
||||
import { HttpServerHelper } from "@spt/helpers/HttpServerHelper";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { pipeline } from 'stream/promises';
|
||||
|
||||
@injectable()
|
||||
export class HttpFileUtil {
|
||||
constructor(@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper) {}
|
||||
|
||||
public sendFile(resp: ServerResponse, filePath: string): void {
|
||||
const pathSlic = filePath.split("/");
|
||||
public async sendFileAsync(resp: ServerResponse, filePath: string): Promise<void> {
|
||||
const pathSlice = filePath.split("/");
|
||||
const type =
|
||||
this.httpServerHelper.getMimeText(pathSlic[pathSlic.length - 1].split(".").at(-1) ?? "") ||
|
||||
this.httpServerHelper.getMimeText(pathSlice[pathSlice.length - 1].split(".").at(-1) ?? "") ||
|
||||
this.httpServerHelper.getMimeText("txt");
|
||||
const fileStream = fs.createReadStream(filePath);
|
||||
|
||||
fileStream.on("open", () => {
|
||||
resp.setHeader("Content-Type", type);
|
||||
fileStream.pipe(resp);
|
||||
});
|
||||
|
||||
await pipeline(fs.createReadStream(filePath), resp);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user