首页 > 解决方案 > Exchange Web 服务订阅错误 - javax.net.ssl.SSLException:对等方重置连接:套接字写入错误

问题描述

我正在使用ews-java-api和 JDK11 创建对 MS Exchange 收件箱的订阅,但我得到了javax.net.ssl.SSLException: Connection reset by peer: socket write error

pom.xml

<dependency>
    <groupId>com.microsoft.ews-java-api</groupId>
    <artifactId>ews-java-api</artifactId>
    <version>2.0</version>
</dependency>
<dependency>
    <groupId>javax.xml.ws</groupId>
    <artifactId>jaxws-api</artifactId>
    <version>2.2.1</version>
</dependency>

代码

public class EwsClient implements DisposableBean {
    private final ExchangeService exchangeService;
    private final int subscriptionLifetimeMinutes;
    private final List<Closeable> closeables = new ArrayList<>();

    // constructor

    public void subscribe(Collection<FolderId> folderIds, EventType[] eventTypes, INotificationEventDelegate eventHandler) throws EwsException {
        try {
            StreamingSubscription subscription = exchangeService.subscribeToStreamingNotifications(folderIds, eventTypes);
            StreamingSubscriptionConnection connection = new StreamingSubscriptionConnection(exchangeService, subscriptionLifetimeMinutes);

            // keep the subscription alive by reconnecting to the Exchange server
            ISubscriptionErrorDelegate disconnectHandler = (sender, args) -> {
                try {
                    connection.open();
                } catch (Exception e) {
                    log.error("Could not reconnect to the exchange server", e);
                }
            };
            connection.addSubscription(subscription);
            connection.addOnNotificationEvent(eventHandler);
            connection.addOnDisconnect(disconnectHandler);
            connection.open();
            closeables.add(connection);
        } catch (Exception e) {
            throw new EwsException(e);
        }
    }

    @Override
    public void destroy() {
        for (Closeable closeable : closeables) {
            try {
                closeable.close();
            } catch (IOException e) {
                log.error("Error closing", e);
            }
        }
        exchangeService.close();
    }
}

堆栈跟踪

Caused by: microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. Connection reset by peer: socket write error
    at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.getEwsHttpWebResponse(ServiceRequestBase.java:729) ~[ews-java-api-2.0.jar:na]
    at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.validateAndEmitRequest(ServiceRequestBase.java:639) ~[ews-java-api-2.0.jar:na]
    at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:62) ~[ews-java-api-2.0.jar:na]
    ... 14 common frames omitted
Caused by: javax.net.ssl.SSLException: Connection reset by peer: socket write error
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:320) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:258) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:988) ~[na:na]
    at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:136) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.impl.io.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:144) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.impl.io.ContentLengthOutputStream.close(ContentLengthOutputStream.java:93) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:157) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123) ~[httpcore-4.4.14.jar:4.4.14]
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.13.jar:4.5.13]
    at microsoft.exchange.webservices.data.core.request.HttpClientWebRequest.executeRequest(HttpClientWebRequest.java:292) ~[ews-java-api-2.0.jar:na]
    at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.getEwsHttpWebResponse(ServiceRequestBase.java:720) ~[ews-java-api-2.0.jar:na]
    ... 16 common frames omitted
    Suppressed: java.net.SocketException: Connection reset by peer: socket write error
        at java.base/java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:na]
        at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110) ~[na:na]
        at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150) ~[na:na]
        at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81) ~[na:na]
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:351) ~[na:na]
        ... 34 common frames omitted
Caused by: java.net.SocketException: Connection reset by peer: socket write error
    at java.base/java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:na]
    at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110) ~[na:na]
    at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketOutputRecord.deliver(SSLSocketOutputRecord.java:320) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:983) ~[na:na]
    ... 31 common frames omitted

标签: javasslexchangewebservices

解决方案


我能够通过将subscriptionLifetimeMinutes值(在 StreamingSubscriptionConnection 构造函数中)从 15 分钟减少到 2 分钟来解决这个问题。根据EWS 文档,订阅连接最多可以打开 30 分钟。我的网络中可能有一条规则在此之前关闭连接。


推荐阅读