亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Javascript?基于長連接的服務框架問題

 更新時間:2022年07月20日 15:36:00   作者:user1516019128585  
本文針對經常使用長連接進行消息收發(fā)的應答場景,采用 Websocket 長連接作為服務監(jiān)聽的對象,模擬了一套類 http 服務框架,通過實例代碼介紹了Javascript?基于長連接的服務框架,需要的朋友可以參考下

背景

經常使用 Node 進行服務端開發(fā)的同學,想必都知道 Koa 框架。Koa 是一種 http 服務框架,其基于洋蔥模型作為基本架構,能夠讓用戶方便快捷地添加中間件,進行業(yè)務開發(fā)。而 websocket 是一種長連接的服務通信協議,需要自定義通訊 api 進行數據通訊。一般情況下,基于 websocket 的通訊 api 也是遵循一問一答的交互模式的,只是通信發(fā)起方可能會是客戶端,也可能會是服務方。

在 MBox 研發(fā)助手的開發(fā)中,前端和服務端處于平等的地位,前端和服務端都有可能發(fā)起請求,所以采用 websocket 協議作為通信協議。在 websocket 基礎上,MBox 研發(fā)助手自定義的通訊 api 與 http 有相似之處,同樣采用一問一答的交互模式。為了減少其他開發(fā)同學的理解成本,維持接口的統(tǒng)一性和可擴展性,在 MBox 研發(fā)助手中我們設計了一套基于長連接的服務框架。

Webscoket 封裝

首先為了方便使用 websocket 接收消息,采用注冊回調函數的方式分發(fā)服務端發(fā)來的消息。

export class Connection {
  private ws: WebSocket = null;
  private handlers: WSHandler[] = [];

  constructor() {
    this.ws = new WebSocket(WSDomain);
    
    this.ws.onmessage = (ev: MessageEvent) => {
      this.handlers.forEach((handler: WSHandler) => {
        handler(ev.data);
      });
    };
  }

  send(data: string): void {
    this.ws.send(data);
  }
  registerRecvHandler(handler: WSHandler): void {
    this.handlers.push(handler);
  }

  close(): void {
    this.ws.close();
  }
}

FakeHttpServer

Context

Koa 的 context 將 resquest和 response 封裝成了一個對象,采用代理的方式來控制對 request 和 response 的訪問,用戶可以通過 context 間接操作 request 和 response。這里忽略了繁瑣的代理內容,簡單將 context 表示為擁有 request 和 response 的簡單對象。Requset 和 Response 類型的具體定義可以根據業(yè)務進行抽象。

export interface Context {
  request: Request;
  response: Response;
}

Middleware

在 Express 和 Koa 等 web 服務框架中,中間件指的是處于 request -response 生命周期中,處理請求的一系列函數。中間件函數對代碼進行了解耦,各個中間件之間無感知,每個中間件只需要處理自己的事情即可。使用 Promise 實現中間件函數的級聯操作,其核心代碼邏輯如下:

export function compose(middleware) {
  if (!Array.isArray(middleware))
    throw new TypeError("Middleware stack must be an array!");
  for (const fn of middleware) {
    if (typeof fn !== "function")
      throw new TypeError("Middleware must be composed of functions!");
  }

  return function (context, next) {
    // last called middleware #
    let index = -1;
    return dispatch(0);
    function dispatch(i) {
      if (i <= index)
        return Promise.reject(new Error("next() called multiple times"));
      index = i;
      let fn = middleware[i];
      if (i === middleware.length) fn = next;
      if (!fn) return Promise.resolve();
      try {
        return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
      } catch (err) {
        return Promise.reject(err);
      }
    }
  };
}

請求處理

了解了 context 和 middleware 級聯處理請求的原理之后,你已經明白 web 服務框架最基本兩個模塊了,下面開始了解 FakeHttpServer 從接收 request 到返回 response 的處理過程。

FakeHttpServer 服務框架基于長連接的特點就體現在使用 websocket 作為底層收發(fā)的數據協議,使用 listen 函數進行請求監(jiān)聽需要傳入一個 Connection 連接而不是端口號。

listen(conn: Connection) {
    this.conn = conn;
    this.conn.registerRecvHandler(this.receive.bind(this));
    
    const fn = compose(this.middlewares);
    this.innerHandleRequest = (
      request: Request,
      response: Response
    ) => {
      const ctx = this.createContext(request, response);
      return this.handleRequest(ctx, fn);
    };
}

receive(data: string) {
    try {
      const obj = JSON.parse(data);
      // 丟掉 respnose 類型的消息
      if (isRequest(obj)) {
        const request = obj as Request;
        const response = {} as Response;

        // 調用 handleRequset
        this.innerHandleRequest(request, response);
      }
    } catch (err) {
      console.error(err);
    }
  }
 private createContext(
   request: Request,
   response: Response
 ): LongContext {
   return { request: request, response: response } as Context;
 }

 private handleRequest(ctx: Context, fnMiddleware) {
   return fnMiddleware(ctx)
     .then(() => this.respond(ctx))
     .catch((err) => console.error(err));
 }

Listen 函數注冊了 Connection 的回調,當客戶端發(fā)送消息時會調用 receive 函數進行處理。首先,FakeHttpServer 會將 Response 類型的消息拋棄,只對 Request 請求消息進行響應。然后,FakeHttpServer 會創(chuàng)建一個新的 context,將 request 和空 response 放入。最后使用 compose 后的中間件函數數組處理請求,返回響應。至此,一個完整的發(fā)起請求到返回響應的流程就結束了。

Quick Start

可以在自定義 Request 和 Response 類型之后,來使用 FakeHttpServer 快速開發(fā)一個基于長連接的 http 模擬服務:

const app = new FakeHttpServer();
app.use((ctx: LongContext, next: Middleware) => {
    ctx.reponse.code = 0;
    next();
});
app.use((ctx: LongContext, next: Middleware) => {
    ctx.reponse.message = "success";
});
app.listen(new Connection());

小結

本文針對經常使用長連接進行消息收發(fā)的應答場景,采用 Websocket 長連接作為服務監(jiān)聽的對象,模擬了一套類 http 服務框架。該框架結合了長連接自定義通訊 api 的靈活和 http 服務框架的自動應答處理機制,提供了一種開銷小、方便、統(tǒng)一、標準化的方式來使用長連接進行數據通訊。

到此這篇關于Javascript 基于長連接的服務框架的文章就介紹到這了,更多相關js長連接服務框架內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論