001/** 002 * 003 * Copyright 2020 Aditya Borikar, 2020-2021 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smack.websocket.okhttp; 018 019import java.util.logging.Level; 020 021import javax.net.ssl.SSLSession; 022 023import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal; 024import org.jivesoftware.smack.websocket.impl.AbstractWebSocket; 025import org.jivesoftware.smack.websocket.rce.WebSocketRemoteConnectionEndpoint; 026 027import okhttp3.OkHttpClient; 028import okhttp3.Request; 029import okhttp3.Response; 030import okhttp3.WebSocket; 031import okhttp3.WebSocketListener; 032 033public final class OkHttpWebSocket extends AbstractWebSocket { 034 035 private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient(); 036 037 private final WebSocket okHttpWebSocket; 038 039 OkHttpWebSocket(WebSocketRemoteConnectionEndpoint endpoint, 040 ModularXmppClientToServerConnectionInternal connectionInternal) { 041 super(endpoint, connectionInternal); 042 043 final String url = endpoint.getRawString(); 044 Request request = new Request.Builder() 045 .url(url) 046 .header(SEC_WEBSOCKET_PROTOCOL_HEADER_FILED_NAME, SEC_WEBSOCKET_PROTOCOL_HEADER_FILED_VALUE_XMPP) 047 .build(); 048 049 okHttpWebSocket = OK_HTTP_CLIENT.newWebSocket(request, listener); 050 } 051 052 private final WebSocketListener listener = new WebSocketListener() { 053 054 @Override 055 public void onOpen(WebSocket webSocket, Response response) { 056 LOGGER.log(Level.FINER, "OkHttp invoked onOpen() for {0}. Response: {1}", 057 new Object[] { webSocket, response }); 058 future.setResult(OkHttpWebSocket.this); 059 } 060 061 @Override 062 public void onMessage(WebSocket webSocket, String text) { 063 onIncomingWebSocketElement(text); 064 } 065 066 @Override 067 public void onFailure(WebSocket webSocket, Throwable throwable, Response response) { 068 LOGGER.log(Level.FINER, "OkHttp invoked onFailure() for " + webSocket + ". Response: " + response, throwable); 069 onWebSocketFailure(throwable); 070 } 071 072 @Override 073 public void onClosing(WebSocket webSocket, int code, String reason) { 074 LOGGER.log(Level.FINER, "OkHttp invoked onClosing() for " + webSocket + ". Code: " + code + ". Reason: " + reason); 075 } 076 077 @Override 078 public void onClosed(WebSocket webSocket, int code, String reason) { 079 LOGGER.log(Level.FINER, "OkHttp invoked onClosed() for " + webSocket + ". Code: " + code + ". Reason: " + reason); 080 } 081 082 }; 083 084 @Override 085 public void send(String element) { 086 okHttpWebSocket.send(element); 087 } 088 089 @Override 090 public void disconnect(int code, String message) { 091 LOGGER.log(Level.INFO, "WebSocket closing with code: " + code + " and message: " + message); 092 okHttpWebSocket.close(code, message); 093 } 094 095 @Override 096 public SSLSession getSSLSession() { 097 // TODO: What shall we do about this method, as it appears that OkHttp does not provide access to the used SSLSession? 098 return null; 099 } 100}