java - 在tomcat中关闭浏览器以进行websocket连接时刷新时在tomcat控制台中引发错误
问题描述
我是一个应用程序,我想在其中保持心跳以检查我的浏览器是否已连接。所以为此我实现了一个网络套接字。我在后端使用java,在前端使用angular 5。
我的代码片段java
@ServerEndpoint(value = "/endpoint", configurator = HttpSessionConfigurator.class)
public class WebServer {
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
log.debug("on open session: "+ session.getId());
this.httpSession = (HttpSession) config.getUserProperties().get(IBClientConstants.HTTP_SESSION);
}
@OnClose
public void onClose(Session session) {
log.debug("onClose session: "+ session.getId());
}
@OnMessage
public void onMessage(String message, Session session) {
String data = "success";//i send some data which is needed in UI
session.getBasicRemote().sendText(data);
}
@OnError
public void onError(Throwable t) {
log.debug(t.getMessage());
}
}
我的 Angular 侧代码:
@Injectable()
export class WebSocketClient {
private webSocket;
private websocketUrl;
constructor(private appConfig: AppConfig) {
this.websocketUrl = appConfig.getBaseURLWithContextPath();
if (this.websocketUrl) {
this.websocketUrl = this.websocketUrl.replace("http", "ws") + "/endpoint"
}
this.webSocket = new WebSocket(this.websocketUrl);
}
connect() {
try {
this.webSocket.onopen = (event) => {
console.log('onopen::' + JSON.stringify(event, null, 4));
}
this.webSocket.onmessage = (event) => {
var response = event.data;
let jsonData = JSON.parse(response);
//i use this data
}
this.webSocket.onclose = (event) => {
console.log('onclose::' + JSON.stringify(event, null, 4));
}
this.webSocket.onerror = (event) => {
console.log('onerror::' + JSON.stringify(event, null, 4));
}
} catch (exception) {
console.error(exception);
}
}
getStatus() {
return this.webSocket.readyState;
}
ping() {
if (this.webSocket.readyState == WebSocket.OPEN) {
this.webSocket.send("ping");
} else {
console.error('webSocket is not open. readyState=' + this.webSocket.readyState);
}
}
disconnect() {
console.log("disconnect");
if (this.webSocket.readyState == WebSocket.OPEN) {
this.webSocket.close();
} else {
console.error('webSocket is not open. readyState=' + this.webSocket.readyState);
}
}
}
所有功能都运行良好。但是当我使用 https 连接时,这意味着我的 websocket url 变为 wss://localhost:8443/InBetween/endpoint。此时,如果我在 chrome 中刷新浏览器,它会在控制台中引发异常。以下是例外。:
Aug 13, 2018 12:11:07 PM
org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer doClose
INFO: Failed to close the ServletOutputStream connection cleanly
java.io.IOException: An established connection was aborted by the
software in your host machine
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:51)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
at org.apache.tomcat.util.net.SecureNioChannel.flush(SecureNioChannel.java:135)
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:370)
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:398)
at org.apache.coyote.http11.upgrade.NioServletOutputStream.doClose(NioServletOutputStream.java:137)
at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.close(AbstractServletOutputStream.java:100)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doClose(WsRemoteEndpointImplServer.java:138)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.close(WsRemoteEndpointImplBase.java:597)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:113)
我尝试在关闭时在浏览器刷新时调用 disconnect()。但这并没有帮助。我在 IE 中进行了同样的测试,它没有给出任何错误。
我的 https 连接器:
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="200" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="some path" keystorePass="password"/>
解决方案
问题是因为网络套接字没有正确断开连接。我this.webSocket = new WebSocket(this.websocketUrl);
从构造函数中删除并添加了一个单独的函数来连接并在需要连接到 Web 套接字的地方使用它。在浏览器刷新和关闭时也称为断开功能。
推荐阅读
- javascript - 如何在会话存储中存储变量
- python-3.x - 嗨,我正在尝试在非空对象中找到一个对象
- symfony - Symfony 5 项目没有安装 stof-doctrine-extensions
- firebase - 特定于域的 Firebase 安全规则
- apache-nifi - 内部 https 负载均衡器 GCP 后面的 Nifi 实例
- python - Plotly:如何处理箱线图中类别之间的不均匀差距?
- xml - Windows 更新后的网站面板错误:XML 文档中不允许输入类型
- html - 如何使用 flex 方向将多个 div 定位在 div 内的不同位置?
- r - 如何解析要用作标签的表达式(ggplot2)
- python - 在python中转换为二进制补码