我有一个使用WebSocket库(ws
)的节点应用程序,并且能够在本地计算机上运行此应用程序。
但是,当我将其发布到Azure App Service时,对于相同的代码会出现以下错误。
我检查了两个节点都在运行相同版本的节点12.13.0,我已经完成了npm install
,并且这些软件包看起来是相同的(无论如何,它们也都包含在内)。而且下面的错误实际上是在抱怨ws
模块中的文件。
触发此错误的代码行是:var WebSocket = require('ws');
Wed Dec 04 2019 13:03:04 GMT+0000 (Coordinated Universal Time): Application has thrown an uncaught exception and is terminated:
SyntaxError: Unexpected token {
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (D:\home\site\wwwroot\node_modules\ws\index.js:3:19)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
Application has thrown an uncaught exception and is terminated:
SyntaxError: Unexpected token {
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (D:\home\site\wwwroot\node_modules\ws\index.js:3:19)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
答案 0 :(得分:0)
作为参考,我试图使GitHub存储库examples/server-stats/
的示例websockets/ws
适用于本地和Azure应用服务。
首先,我将所有源代码下载到本地计算机上,并在本地目录(如下图所示)中运行npm install
和npm install ws
。
图1.示例server-stats
的本地文件结构。
第二,我尝试使用命令node index.js
直接运行它并遇到问题Error: Cannot find module '../..'
,然后我将文件index.js
更改为以下代码。
const WebSocket = require('ws'); // The original content is `require('../..')`
然后,我运行node index.js
并打开浏览器以查看结果,效果很好。
图2。server-stats
在本地运行正常
众所周知,Azure App Service要求节点应用程序绑定代码process.env.PORT
中的端口值并以web.config
文件启动,因此我更改了index.js
文件,并创建了一个web.config
文件,其内容来自Kudu Wiki页面Using a custom web.config for Node apps
,并使用index.js
代替server.js
,其代码如下。
index.js
const port = 8080;
server.listen(port, function() {
console.log('Listening on http://localhost:'+port);
});
web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
This configuration file is required if iisnode is used to run node processes behind
IIS or IIS Express. For more information, visit:
https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->
<configuration>
<system.webServer>
<!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
<webSocket enabled="false" />
<handlers>
<!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="index.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<!-- Do not interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^index.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="index.js"/>
</rule>
</rules>
</rewrite>
<!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<!--
You can control how Node is hosted within IIS using the following options:
* watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
* node_env: will be propagated to node as NODE_ENV environment variable
* debuggingEnabled - controls whether the built-in debugger is enabled
See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
-->
<!--<iisnode watchedFiles="web.config;*.js"/>-->
</system.webServer>
</configuration>
然后,我将所有文件和目录上传到Azure WebApp,如下图所示,在其Kudu控制台中查看。
图3.通过Kudu Console在Azure WebApp上的示例文件结构
在我为WEBSITE_NODE_DEFAULT_VERSION
添加新的重新编码12.13.0
和Application settings
后,
图4.通过WEBSITE_NODE_DEFAULT_VERSION
中的Application settings
设置节点运行时版本
我在浏览器中打开了它,它确实起作用了。
图5.对于具有默认设置的websocket功能,它不起作用
上面的结果有两个问题。
对于使用websocket的Web应用程序,需要在Web sockets
中启用功能General settings
。
图6.要在Web sockets
中启用General settings
默认情况下,Azure启用了SSL来进行HTTP访问,因此,对于wss
文件中的Websocket URL,必须使用ws
而不是public/index.html
。
图7.使用wss
代替ws
中的public/index.html
来在Azure App Service上启用SSL。
最后,它可以在Azure App Service上运行。