我试图在Angular Universal的Express应用程序中调用WebSocket服务器。
在使用npm run serve:ssr
时,它在生产环境中工作正常
> [email protected] serve:ssr
> node dist/evaluator/server/main.js
Node Express app listening on http://localhost:4000
字符串
我可以在ws://localhost:4000
上调用WebSocket
但是,在使用npm run dev:ssr
的本地开发模式中,
生成器中的以下代码行
https://github.com/angular/universal/blob/main/modules/builders/src/ssr-dev-server/utils.ts#L22
export function getAvailablePort(): Promise<number> {
return new Promise((resolve, reject) => {
const server = createServer();
server
.unref()
.on('error', reject)
.listen(0, () => {
const { port } = server.address() as AddressInfo;
server.close(() => resolve(port)); // This port is random
});
});
}
型
为Express Server(SSR)设置一个影响process.env['PORT']
的随机端口。
server.ts中的代码(快速服务器端)
export function app(): express.Express {
const express_app = express();
// ....
return express_app;
}
function run(): void {
const port = process.env['PORT'] || 4000; // that process port comes from the above builder utils
// Start up the Node app
const express_app = app();
const server = http.createServer(express_app);
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
ws.send(JSON.stringify('mess ' + message));
});
});
server.listen(port, () => {
console.log(`Node Express app listening on http://localhost:${port}`);
});
}
型
此注解说明您可以通过配置设置端口
https://github.com/angular/universal/issues/1628#issuecomment-616322722
但在我看来,有一个与角默认4200端口混淆(你可以在angular.json中设置,如文档https://github.com/angular/universal/blob/main/modules/builders/README.md#ssr-dev-server所述),但它不影响Express服务器端口,它总是随机的。
如果我在/node_modules/@nguniversal/builders/src/ssr-dev-server/utils.jsL27中强制端口为4000,那么express应用程序将在端口4000上启动,然后我可以在proxy.conf.json中代理请求,例如
{
"/ws": {
"target": "ws://localhost:4000",
"secure": false,
"ws": true
}
}
型
否则,我不知道如何获得动态端口来请求WebSocket。看起来Angular Universal的代理魔法只代理http://localhost:4200/
到express路由器,而不是ws://localhost:4200/
。因此,我请求WebSocket的唯一方法是将ws://localhost:4200/ws
转换为ws://localhost:4000/
我在app.component.ts中的代码(Angular 前端)
constructor(
@Inject(PLATFORM_ID) private platformId: InjectionToken<Record<string, unknown>>,
@Inject(DOCUMENT) private document: Document
) {
this.window = this.document.defaultView as Window;
if (this.isBrowser) {
const myWebSocket = webSocket(this.window.location.href.replace('http', 'ws'));
// open a socket to ws://localhost:4200/
// so here the PORT is not correct ws://localhost:4200/ does not reply
// because the port is dynamicaly set unless I hard fix it to 4000 in utils
// and set it here too instead of Angular 4200 port
myWebSocket.asObservable().subscribe(dataFromServer => {
console.log(dataFromServer);
});
myWebSocket.next(JSON.stringify({}));
}
型
我的问题是我如何设置这个端口或者如何在Angular 侧获得这个动态进程.env“PORT”]?
Compiled successfully.
Node Express app listening on http://localhost:43481 // How can I set this port ? or how can I get it in app component
** Angular Universal Live Development Server is listening on http://localhost:4200, open your browser on http://localhost:4200 **
型
相关信息:
WebSocket with angular universal
https://github.com/angular/universal/issues/1848的
https://github.com/angular/universal/issues/1722的
感谢您的阅读
1条答案
按热度按时间ewm0tg9j1#
我今天刚遇到这个问题,这确实很令人沮丧。我解决这个问题的方法是在
development
上创建另一个服务器(wss),但使用与production
上的express服务器相同的服务器:字符串
这是
initWSS
:型
因此,如果环境是
development
,那么创建另一个wss服务器,并将其分配到一个固定端口(wss为4202,主服务器为4201),否则,只需在生产环境中将express和wss服务器加入process.env['PORT']
。