uni-app 支付宝云的Unicloud中使用websocket一直报异常"java.nio.channels.ClosedChannelException"
uni-app 支付宝云的Unicloud中使用websocket一直报异常"java.nio.channels.ClosedChannelException"
示例代码:
module.exports = {
_before: function() { // 通用预处理器
},
_onWebsocketConnection: async function(event) {
console.log("onWebsocketConnection", event)
},
_onWebsocketMessage: async function(event) {
console.log("onWebsocketMessage", event)
const connectionId = event.connectionId;
const ws = uniCloud.webSocketServer()
await ws.close(connectionId)
},
_onWebsocketDisConnection: async function(event) {
console.log("onWebsocketDisConnection", event)
},
_onWebsocketError: async function(event) {
console.log("onWebsocketError", event)
},
getWsURL: async function() { // 获取websocket连接地址
console.log("getWsURL被调用")
const wsRequestParamsObj = {
hostIP: "192.1.1.1",
command: "1"
}
const ws = uniCloud.webSocketServer()
const hostURL = await ws.signedURL("web-socket-co", wsRequestParamsObj)
return hostURL
},
}
操作步骤:
- 上传云对象
- 用apifox请求URL化的云对象的getWsURL获得ws的连接地址
- 用连接地址连接
- 发送一条消息
预期结果:
没有进入到_onWebsocketError事件中
实际结果:
进入了_onWebsocketError事件中,并且报错:“java.nio.channels.ClosedChannelException”
bug描述:
以下是我云对象的全部代码,非常规范的事件处理,但是每当连接上websocket服务后,发送一条消息,ws连接会断开,这个没问题. 但是为什么_onWebsocketError触发了?而且通过云对象的后台日志发现报"java.nio.channels.ClosedChannelException"这个错误?(具体请看第四张图) 我只连接ws,手动断开ws连接,观察后台日志就没有这个报错?这个是为什么?
回复 c***@163.com: 现在还会有这个问题吗?
方便的话私信我一下。
解决了吗
在uni-app结合支付宝云的Unicloud使用WebSocket时遇到java.nio.channels.ClosedChannelException
异常,通常表明WebSocket连接在某个时刻被意外关闭了。这个异常可能由多种原因引起,包括客户端断开连接、服务器端主动关闭连接、网络问题或配置错误等。
为了解决这个问题,我们需要确保WebSocket连接的正确管理,包括连接的建立、数据传输和连接的关闭。下面是一个简化的示例,展示了如何在UniCloud云函数中管理WebSocket连接,同时处理可能的异常,包括ClosedChannelException
。
服务器端代码(UniCloud云函数)
// 引入必要的模块
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
// 存储所有连接的客户端
const clients = new Set();
server.on('connection', (ws) => {
clients.add(ws);
console.log('New client connected');
ws.on('message', (message) => {
console.log(`Received message => ${message}`);
// 广播消息给所有客户端
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
ws.on('close', () => {
clients.delete(ws);
console.log('Client disconnected');
});
ws.on('error', (error) => {
if (error instanceof WebSocket.errors.ClosedError) {
console.error('WebSocket connection closed unexpectedly:', error);
} else {
console.error('WebSocket error:', error);
}
clients.delete(ws);
});
});
console.log('WebSocket server is running on ws://localhost:8080');
客户端代码(uni-app)
const ws = uni.connectSocket({
url: 'ws://your-server-address:8080',
});
ws.onMessage((res) => {
console.log('Received:', res.data);
});
ws.onError((err) => {
console.error('WebSocket error:', err);
// 根据错误类型决定是否重连
if (err.errMsg.includes('ClosedChannelException')) {
// 处理特定异常,比如尝试重连
console.error('Handling ClosedChannelException, attempting to reconnect...');
// 重连逻辑...
}
});
ws.onClose((res) => {
console.log('WebSocket connection closed:', res);
// 根据需要实现重连逻辑
});
// 发送消息
ws.send({
data: 'Hello Server',
});
请注意,上述代码是简化的示例,用于说明如何在服务器端和客户端处理WebSocket连接。在实际应用中,你可能需要根据具体需求添加更多的错误处理和连接管理逻辑。同时,确保服务器端地址和端口配置正确,以及网络环境稳定。