在我的小项目中,我想构建一个可以使用 Raspberry Pi Zero 从任何网络浏览器访问的 BabyCam。为此,我想使用express-is 打开一个网络套接字,将视频流式传输到多个客户端。我将大部分视频相关代码基于 raspivid-stream 模块。但是,当尝试访问 Web 套接字时,我收到
app.ws(...
的类型错误,指出 Property 'ws' does not exist on type 'Application'
。当然,我导入了express和express-ws的类型。
我不太确定问题是什么,因为 JavaScript 中的相同调用似乎工作正常。这是代码 - 我很高兴获得任何帮助!
import express from 'express';
import { Request, Response } from 'express';
import fs from 'fs';
import https from 'https';
import http from 'http';
import raspividStream from 'raspivid-stream';
import expressWs from 'express-ws';
const server: express.Application = express();
const httpPort: number = 8080;
const httpsPort: number = 8443;
const sslCredentials = {
key: fs.readFileSync('../ssl/localhost.key', 'utf8'),
cert: fs.readFileSync('../ssl/localhost.cert', 'utf8')
};
// CREATE SERVER
const httpServer = http.createServer(server);
const httpsServer = https.createServer(sslCredentials, server);
expressWs(server, httpsServer);
// ROUTES
server.get('*', (req: Request, res:Response) => {
if (!req.secure) {
return res.redirect(`https://${req.hostname}:${httpsPort}${req.originalUrl}`);
}
res.sendFile(__dirname + '/client/index.html');
});
// WEBSOCKET
server.ws('/video-stream', (ws) => {
console.log('Client connected');
ws.send(JSON.stringify({
action: 'init',
width: '960',
height: '540'
}));
var videoStream = raspividStream({ rotation: 180 });
videoStream.on('data', (data) => {
ws.send(data, { binary: true }, (error) => { if (error) console.error(error); });
});
ws.on('close', () => {
console.log('Client left');
videoStream.removeAllListeners('data');
});
});
// START SERVER
httpServer.listen(httpPort, () => {
console.log(`BabyCam (redirect) listening at http://localhost:${httpPort}/`);
});
httpsServer.listen(httpsPort, () => {
console.log(`BabyCam (SSL) listening at https://localhost:${httpsPort}/`);
});
Property 'ws' does not exist on type 'Application'
是一个 typescript 错误,表明 typescript 不知道 ws()
上的 app
方法。预计为 express
定义的 TS 类型不包含该方法(因为它不是 express
API 的内置部分。)
ws()
方法来自express-ws
模块,作为“混合”。为了获得反映这一点的值,我们需要访问 express-ws
添加的类型,我们可以执行以下操作...
首先,确保您安装了
express
和 express-ws
的 TS 类型:
npm install @types/express @types/express-ws
然后创建
server
,如下所示:
const expressServer = express(); // Type = Express
const wsServer = expressWs(expressServer); // Type = expressWs.Instance
const server = wsServer.app; // type = wsExpress.Application
注意:
server
和 expressServer
的运行时值在运行时是相同的。它是同一个 Express 实例(这就是为什么你的代码在作为普通 JS 运行时工作正常的原因)。我们只是以稍微不同的方式处理事情,以便让 Typescript 了解类型发生的情况。
Express.Application 没有名为 ws 的成员。这就是你得到的错误。您需要使用expressWS(server, httpsServer)的返回值。您可以在那里访问的应用程序类型为 Express.Application & WithWebsocketMethod。