【发布时间】:2020-07-08 16:36:40
【问题描述】:
我只在远程服务器端遇到问题,这意味着即使通过 https 的自签名证书在本地也能正常工作。但是当我将代码移动到服务器时,它在本地也可以工作,但不能在远程工作。
我创建了一个节点应用程序,该应用程序托管在 https 端口 3000 下的服务器中。该应用程序具有 Socket IO 库,我已将其附加到同一个 https 服务器。我没有使用 nodeiis,因为我使用重写规则通过 Windows IIS 传递它。
我已经在 IIS 中安装了 websocket 模块。事实上,我已经在使用 websockets 而不是 Socket.IO,而且它在与我现在的配置相同的情况下运行良好,我只是用 Socket.IO 替换了它,因为它更适合我的需要。
现在是我的代码
HTML页面
<script src="/socket.io/socket.io.js"></script>
<script src="/js/Client.js"></script>
客户端.js
$(document).ready(function() {
var address = window.location.protocol + '//' + window.location.host;
var details = {
resource: (window.location.pathname.split('/').slice(0, -1).join('/') + '/socket.io').substring(1)
};
const socket = io.connect(address, details);
socket.on('connect', function () {
console.log('Client Connected');
socket.emit('ping', 'hi server ping sent!');
});
socket.on('error', function (reason){
console.log('Connection failed', reason); //Here is where it launch the error
});
});
App.js
....
const https = require('https');
var socketlib = require('./socketLib');
const fs = require('fs');
const app = express();
var cookieParser = require('cookie-parser');
app.use(sessionParser);
var expiryDate = new Date( Date.now() + 60 * 60 * 1000 );
const sessionParser = session({
secret: 'secret', resave: true, cookieName: 'sessionName',
name: 'sessionId', saveUninitialized: true,
ephemeral: true,
cookie: { secure: true, expires: expiryDate, SameSite : 'None',
maxAge: 24000 * 60 * 60, // One hour
}
});
//// HTTPS Server ////
const options = {
key: fs.readFileSync(config.certKey),
cert: fs.readFileSync(config.certCert)
};
var httpsServer = https.createServer(options, app, function (req, res) {
console.log('request starting...https');
});
httpsServer.listen(3000, function(req, res) {
console.log('Server is running at', config.nodeApiUrl + ':', port)
});
socketlib(httpsServer, sessionParser);
app.all('/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', 'https://localhost:3000')
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Access-Token,X-Key");
return next();
})
socketLib.js
module.exports = async function(httpsServer, sessionParser) {
var io = require("socket.io")(httpsServer);
io.use(function(socket, next) {
sessionParser(socket.request, socket.request.res, next);
});
io.use((socket, next) => {
if (socket.request.headers.cookie)
return next();
next(new Error('Authentication error'));
});
io.sockets.on('connection', function(socket) {
console.log(`New connection from: ${socket.handshake.address}`)
});
}
iis 网络配置
<rule name="Websocket" stopProcessing="true" enabled="true">
<match url="socket.io" ignoreCase="true" />
<action type="Rewrite" url="https://localhost:3000/{R:0}/socket.io.js" appendQueryString="false" redirectType="Found" />
<conditions>
<add input="{HTTP_HOST}" pattern="domainxxx.com" />
</conditions>
</rule>
这是我在浏览器控制台中看到的错误
socketio.js:57 Error Error: server error
at r.onPacket (socket.io.js:7)
at o.<anonymous> (socket.io.js:7)
at o.r.emit (socket.io.js:6)
at o.r.onPacket (socket.io.js:7)
at n (socket.io.js:7)
at Object.e.decodePayload (socket.io.js:7)
at o.r.onData (socket.io.js:7)
at i.<anonymous> (socket.io.js:7)
at i.r.emit (socket.io.js:6)
at i.onData (socket.io.js:7)
如果我点击任何这些行,这就是我要到的地方:
switch(a('socket receive: type "%s", data "%s"',t.type,t.data),this.emit("packet",t),this.emit("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var e=new Error("server error");e.code=t.data,this.onError(e);break;
你会看到:
var e=new Error("server error")
最后,基本上当我尝试通过 domainxxx.com 访问时,就像发生套接字无法远程连接的事情一样,本地工作正常,所以我想唯一的问题是在重写规则之后,因为我可以看到,重写规则是 100% 正确的,但显然我遗漏了一些东西。
我希望你能帮助我!我做了很多研究,但找不到解决方法!
提前谢谢你!
【问题讨论】:
-
如果它不能远程工作并且这是一个托管服务器,那么很可能需要修复托管配置中的某些内容(代理、负载平衡器等...)以正确允许持久化webSocket 连接。
-
感谢@jfriend00 的这些帖子。运气好的话,我可以修复它。问题与重写规则有关!再次感谢您!
-
如果您愿意,您可以为自己的问题写一个答案,说明您缺少什么。我不太了解 IIS,无法写一个答案。
-
我刚做了。谢谢!
标签: javascript node.js express sockets socket.io