最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

express中創(chuàng)建 websocket 接口及問題解答

 更新時間:2022年05月23日 14:48:11   作者:程序媛李李李李李蕾  
本文主要介紹了express中創(chuàng)建 websocket 接口及問題解答,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

大多數(shù)文章里的方法是直接安裝 express-ws 然后進(jìn)行使用:

const express = require(`express`)
const server = express()
const expressWs = require(`express-ws`)
expressWs(server)

server.ws(`/aaa`, (ws, req) => {
  console.log(`socket`, req.testing)
  ws.send(`aaa`)
  ws.on(`message`, function(msg) {
    console.log(msg)
  })
})
server.get(`/bbb`, (req, res) => {
  res.json(`bbb`)
})
server.listen(3040)

可以看到在上面創(chuàng)建了一個 ws://127.0.0.1:3040/aaa 這樣的 websoket 接口, 然而當(dāng)我們嘗試 new WebSocket("ws://127.0.0.1:3040/ccc") 時, 也能連接上, 這雖然不會影響我們的業(yè)務(wù), 但沒有創(chuàng)建的接口能連上, 顯然是很不好的.

在 express-ws 的 github 倉庫和問題列表中看了很久沒有找到解決方法, 然后就去看它的代碼. 發(fā)現(xiàn)代碼不多, 卻拆分了很多文件, 然而代碼沒多少我卻很難看懂.

整理 express-ws 源碼

然后先合并一些分散在各個文件里的代碼和注釋:

function expressWs(app, httpServer, options = {}) {
  addWsMethod(app)
  const server = http.createServer(app)
  app.listen = function serverListen(...args) {
    return server.listen(...args)
  }
  const wsServer = new ws.Server({server})
  wsServer.on(`upgrade`, async (req, socket, upgradeHead) => {
    const res = new http.ServerResponse(req)
    return server(req, res)
  })
  wsServer.on(`connection`, (socket, request) => {
    if (`upgradeReq` in socket) {
      request = socket.upgradeReq
    }
    request.ws = socket
    request.wsHandled = false
    request.url = websocketUrl(request.url)
    const dummyResponse = new http.ServerResponse(request)
    dummyResponse.writeHead = function writeHead(statusCode) {
      if (statusCode > 200) {
        dummyResponse._header = `` // eslint-disable-line no-underscore-dangle
        socket.close()
      }
    }
    app.handle(request, dummyResponse, () => {
      if (!request.wsHandled) {
        socket.close()
      }
    })
  })
}

function trailingSlash(string) {
  let suffixed = string
  if (suffixed.charAt(suffixed.length - 1) !== `/`) {
    suffixed = `${suffixed}/`
  }
  return suffixed
}


function websocketUrl(url) {
  if (url.indexOf(`?`) !== -1) {
    const [baseUrl, query] = url.split(`?`)
    return `${trailingSlash(baseUrl)}.websocket?${query}`
  }
  return `${trailingSlash(url)}.websocket`
}


function addWsMethod(target) {
  if (!target.ws) {
    target.ws = function (route, ...middlewares) {
      const wrappedMiddlewares = middlewares.map((function (middleware) {
        return (req, res, next) => {
          if (req.ws) {
            req.wsHandled = true
            try {
              middleware(req.ws, req, next)
            } catch (err) {
              next(err)
            }
          } else {
            next()
          }
        }
      }))
      const wsRoute = websocketUrl(route)
      this.get(...[wsRoute].concat(wrappedMiddlewares))
      return this
    }
  }
}

把源碼整理出來, 看起來確實沒多少. 然而還是有些難看懂, 并且沒有解決上面所說的沒有創(chuàng)建的接口也會連接的問題, 那么我整理源代碼有何用?

拿著源碼改了半天, 還是沒有解決. 所以, 再去一下層看看能不能找到方法.

于是就來到了 express-ws 使用的 ws, 看 ws 的使用量和活躍度都十分可觀, 應(yīng)該能解決我的問題, 如果不能解決, 就是我的問題~~~

摒棄 express-ws

先脫離 express-ws 自身的那個思想, 仔細(xì)看了半天文檔, 看到 readme 里有有個示例: 演示了從 ws 連接時如何根據(jù)路由分發(fā)到不同的 ws 服務(wù).

import { createServer } from 'http';
import { parse } from 'url';
import { WebSocketServer } from 'ws';

const server = createServer();
const wss1 = new WebSocketServer({ noServer: true });
const wss2 = new WebSocketServer({ noServer: true });

wss1.on('connection', function connection(ws) {
  // ...
});

wss2.on('connection', function connection(ws) {
  // ...
});

server.on('upgrade', function upgrade(request, socket, head) {
  const { pathname } = parse(request.url);

  if (pathname === '/foo') {
    wss1.handleUpgrade(request, socket, head, function done(ws) {
      wss1.emit('connection', ws, request);
    });
  } else if (pathname === '/bar') {
    wss2.handleUpgrade(request, socket, head, function done(ws) {
      wss2.emit('connection', ws, request);
    });
  } else {
    socket.destroy();
  }
});

server.listen(8080);

分發(fā)服務(wù)例子里有了演示, 但是能不能做到 express 那樣通過 app.ws('/a') app.ws('/b') 的形式進(jìn)行分發(fā)呢? 能不能實現(xiàn)像 express 一樣支持路徑參數(shù)呢?

當(dāng)前 express-ws 是沒有支持路徑參數(shù)的, 并且已經(jīng)有一年沒有活躍了.

自己思考實現(xiàn) express-ws 并解決它存在的問題

首先 app.ws 可以直接在 express 實例是通過 app.ws = fn 的實現(xiàn). 然后 ws 對應(yīng)的不同路由對應(yīng)到不同的處理方法如何實現(xiàn)呢?

那就先以路由為 key, 然后處理方法為 value 保存起來, 到時候根據(jù)訪問的 url 查找對應(yīng)的 key/value 執(zhí)行就行.

如何根據(jù) url 查找 key? 我們在 ws 提供的示例中發(fā)現(xiàn)在 server.on('upgrade') 這一層可以進(jìn)行查找和分發(fā), 然后好像思路上沒什么大問題, 測試了一下確實可以.

以下是代碼:

function expressWs(app) {
  const server = http.createServer(app)
  server.on(`upgrade`, (req, socket, head) => {
    const obj = app.wsRoute[req.url]
    obj ? obj.wss.handleUpgrade(req, socket, head, ws => obj.mid(ws, req)) : socket.destroy()
  })
  app.listen = (...arg) => server.listen(...arg)
  app.ws = (route, mid) => {
    app.wsRoute = app.wsRoute || {}
    app.wsRoute[route] = {
      wss: new Server({ noServer: true }),
      mid,
    }
  }
}

使用方式依然是:

const express = require(`express`)
const server = express()
expressWs(server)

server.ws(`/aaa`, (ws, req) => {
  console.log(`socket`, req.testing)
  ws.send(`aaa`)
  ws.on(`message`, function(msg) {
    console.log(msg)
  })
})
server.get(`/bbb`, (req, res) => {
  res.json(`bbb`)
})
server.listen(3040)

測試了一下連接不存在的 ws 接口, 能按預(yù)期工作, 不存在就連接不上, 存在的能連接上, http 接口也能正常工作.

但是, 我的代碼好像更少呢~~~

接下來要實現(xiàn)其他的功能就很簡單了: 例如

  • 支持 express 的路由模式, 例如 /ws/:id
  • 支持讀取 params, query 參數(shù)

為什么要折騰這個?

因為在重構(gòu) https://github.com/wll8/mockm

到此這篇關(guān)于express中創(chuàng)建 websocket 接口及問題解答的文章就介紹到這了,更多相關(guān)express創(chuàng)建 websocket 接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Node.js中module.exports?和exports使用誤區(qū)

    Node.js中module.exports?和exports使用誤區(qū)

    本文主要介紹了Node.js中module.exports?和exports使用誤區(qū),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 在Mac下徹底卸載node和npm的方法

    在Mac下徹底卸載node和npm的方法

    今天小編就為大家分享一篇在Mac下徹底卸載node和npm的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • nodejs實現(xiàn)HTTPS發(fā)起POST請求

    nodejs實現(xiàn)HTTPS發(fā)起POST請求

    這篇文章主要介紹了nodejs實現(xiàn)HTTPS發(fā)起POST請求的實例代碼,非常的簡單實用,有需要的小伙伴可以參考下。
    2015-04-04
  • node以及npm版本不對應(yīng)出錯的完美解決方法

    node以及npm版本不對應(yīng)出錯的完美解決方法

    最近項目用到了node和npm,查看一下當(dāng)前版本,發(fā)現(xiàn)有報錯,下面這篇文章主要給大家介紹了關(guān)于node以及npm版本不對應(yīng)出錯的完美解決方法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 13 個npm 快速開發(fā)技巧(推薦)

    13 個npm 快速開發(fā)技巧(推薦)

    這篇文章主要介紹了13 個npm 快速開發(fā)技巧,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-07-07
  • 簡單了解node npm cnpm的具體使用方法

    簡單了解node npm cnpm的具體使用方法

    這篇文章主要介紹了簡單了解node npm cnpm的具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • NodeJs模擬登陸正方教務(wù)

    NodeJs模擬登陸正方教務(wù)

    網(wǎng)上已經(jīng)有很多關(guān)于模擬登陸正方教務(wù)的作品了,基于 PHP,Python,Java,.Net 加上NodeJs,這幾門語言都可以實現(xiàn)模擬登陸,模擬登陸的技術(shù)點(diǎn)不是特別難,這里記錄一下利用Node碰到的一些坑,以及一些解決思路。
    2017-04-04
  • nodeJS模塊簡單用法示例

    nodeJS模塊簡單用法示例

    這篇文章主要介紹了nodeJS模塊簡單用法,結(jié)合實例形式簡單分析了nodejs模塊定義、引入、注冊、啟動等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • npm?install安裝過程報錯的實用解決辦法

    npm?install安裝過程報錯的實用解決辦法

    最近做項目遇到npm install 的問題,下面這篇文章主要給大家介紹了關(guān)于npm?install安裝過程報錯的實用解決辦法,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Node.js的基本知識簡單匯總

    Node.js的基本知識簡單匯總

    本文主要給大家簡單介紹了Node.js的基本知識,包括概念、特點(diǎn)、歷史、案例的相關(guān)資料,需要的朋友可以參考下
    2016-09-09

最新評論

五大连池市| 高尔夫| 禄丰县| 红原县| 托克逊县| 桐城市| 茌平县| 晋中市| 宣汉县| 井冈山市| 岳西县| 德保县| 城步| 宁海县| 日喀则市| 昭平县| 西安市| 惠来县| 乌鲁木齐市| 股票| 南阳市| 青海省| 安阳市| 阿坝县| 岚皋县| 平遥县| 衡水市| 仪征市| 黑河市| 长岛县| 南安市| 潍坊市| 磐安县| 肥西县| 永兴县| 湖口县| 日照市| 溧水县| 长白| 富源县| 富顺县|