当咱们应用Socket开发服务器间互相通信的时候,应该都遇到这个异样,失常状况下,这个是因为客户端和服务器端网络异样或者强制断开所产出的异样,具体如下:
java.io.IOException: 近程主机强制敞开了一个现有的连贯。 at sun.nio.ch.SocketDispatcher.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43) at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) at sun.nio.ch.IOUtil.read(IOUtil.java:192) at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253) at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132) at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748)
在网上翻了半天没有找到该异样的解决(屏蔽)办法,于是就本人入手,饥寒交迫吧!
通过查看源码,定位到异样为堆栈信息打印地位:
看名字就能分明这个是默认的异样监听类,该类继承了ExceptionListenerAdapter,而ExceptionListenerAdapter又实现了ExceptionListener 接口,该接口代码如下:
package com.corundumstudio.socketio.listener;import io.netty.channel.ChannelHandlerContext;import java.util.List;import com.corundumstudio.socketio.SocketIOClient;public interface ExceptionListener { void onEventException(Exception e, List<Object> args, SocketIOClient client); void onDisconnectException(Exception e, SocketIOClient client); void onConnectException(Exception e, SocketIOClient client); void onPingException(Exception e, SocketIOClient client); boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception;}
如果咱们要屏蔽这个异样(堆栈信息),就须要从新实现这个接口,而后覆写exceptionCaught办法即可。
新建 MyDefaultExceptionListener 类继承 ExceptionListenerAdapter ,间接上代码:
@Slf4jpublic class MyDefaultExceptionListener extends ExceptionListenerAdapter { public MyDefaultExceptionListener() { super(); } @Override public void onEventException(Exception e, List<Object> args, SocketIOClient client) { log.error(e.getMessage()); } @Override public void onDisconnectException(Exception e, SocketIOClient client) { log.error(e.getMessage()); } @Override public void onConnectException(Exception e, SocketIOClient client) { log.error(e.getMessage()); } @Override public void onPingException(Exception e, SocketIOClient client) { log.error(e.getMessage()); } @Override public boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) { log.error("谬误:" + e.getMessage()); ctx.close(); return true; }}
这个的话,如果出现异常,就不会打印堆栈信息了。
接下来,咱们在Socket的初始化配置类外面设置一下,示例代码:
com.corundumstudio.socketio.Configuration configuration = new com.corundumstudio.socketio.Configuration();////其它配置项略///configuration.setExceptionListener(new MyDefaultExceptionListener());////其它配置项略///return new SocketIOServer(configuration);
这里有个坑须要留神一下,不要在 SocketIOServer 中增加监听,不起作用。
至此,异样覆写实现。
注:本文章应用的是 netty-socketio 作为服务端。引入版本为:
<!--socket通信应用--> <dependency> <groupId>com.corundumstudio.socketio</groupId> <artifactId>netty-socketio</artifactId> <version>1.7.19</version> </dependency>
实现后日志最终打印成果如下,再没有堆栈信息了: