org.java_websocket.client.WebSocketClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Porter-Bridge-Http Show documentation
Show all versions of Porter-Bridge-Http Show documentation
转接远程的http接口,服务器响应正确的数据格式必须是JResponse定义的格式。
客户端websocket使用"org.java-websocket:Java-WebSocket:1.5.2",项目地址https://github.com/TooTallNate/Java-WebSocket;
对Java-WebSocket做了适当修改。
The newest version!
/*
* Copyright (c) 2010-2020 Nathan Rajlich
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.java_websocket.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.java_websocket.AbstractWebSocket;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.enums.Opcode;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.exceptions.InvalidHandshakeException;
import org.java_websocket.framing.CloseFrame;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.HandshakeImpl1Client;
import org.java_websocket.handshake.Handshakedata;
import org.java_websocket.handshake.ServerHandshake;
import org.java_websocket.protocols.IProtocol;
/**
* A subclass must implement at least onOpen, onClose, and
* onMessage to be useful. At runtime the user is expected to establish a connection via
* {@link #connect()}, then receive events like {@link #onMessage(String)} via the overloaded
* methods and to {@link #send(String)} data to the server.
*/
public abstract class WebSocketClient extends AbstractWebSocket implements Runnable, WebSocket {
/**
* The URI this channel is supposed to connect to.
*/
protected URI uri = null;
/**
* The underlying engine
*/
private WebSocketImpl engine = null;
/**
* The socket for this WebSocketClient
*/
private Socket socket = null;
/**
* The SocketFactory for this WebSocketClient
*
* @since 1.4.0
*/
private SocketFactory socketFactory = null;
/**
* The used OutputStream
*/
private OutputStream ostream;
/**
* The used proxy, if any
*/
private Proxy proxy = Proxy.NO_PROXY;
/**
* The thread to write outgoing message
*/
private Thread writeThread;
/**
* The thread to connect and read message
*/
private Thread connectReadThread;
/**
* The draft to use
*/
private Draft draft;
/**
* The additional headers to use
*/
private Map headers;
/**
* The latch for connectBlocking()
*/
private CountDownLatch connectLatch = new CountDownLatch(1);
/**
* The latch for closeBlocking()
*/
private CountDownLatch closeLatch = new CountDownLatch(1);
/**
* The socket timeout value to be used in milliseconds.
*/
private int connectTimeout = 0;
/**
* DNS resolver that translates a URI to an InetAddress
*
* @see InetAddress
* @since 1.4.1
*/
private DnsResolver dnsResolver = null;
/**
* Constructs a WebSocketClient instance and sets it to the connect to the specified URI. The
* channel does not attampt to connect automatically. The connection will be established once you
* call connect.
*
* @param serverUri the server URI to connect to
*/
public WebSocketClient(URI serverUri) {
this(serverUri, new Draft_6455());
}
/**
* Constructs a WebSocketClient instance and sets it to the connect to the specified URI. The
* channel does not attampt to connect automatically. The connection will be established once you
* call connect.
*
* @param serverUri the server URI to connect to
* @param protocolDraft The draft which should be used for this connection
*/
public WebSocketClient(URI serverUri, Draft protocolDraft) {
this(serverUri, protocolDraft, null, 0);
}
/**
* Constructs a WebSocketClient instance and sets it to the connect to the specified URI. The
* channel does not attampt to connect automatically. The connection will be established once you
* call connect.
*
* @param serverUri the server URI to connect to
* @param httpHeaders Additional HTTP-Headers
* @since 1.3.8
*/
public WebSocketClient(URI serverUri, Map httpHeaders) {
this(serverUri, new Draft_6455(), httpHeaders);
}
/**
* Constructs a WebSocketClient instance and sets it to the connect to the specified URI. The
* channel does not attampt to connect automatically. The connection will be established once you
* call connect.
*
* @param serverUri the server URI to connect to
* @param protocolDraft The draft which should be used for this connection
* @param httpHeaders Additional HTTP-Headers
* @since 1.3.8
*/
public WebSocketClient(URI serverUri, Draft protocolDraft, Map httpHeaders) {
this(serverUri, protocolDraft, httpHeaders, 0);
}
/**
* Constructs a WebSocketClient instance and sets it to the connect to the specified URI. The
* channel does not attampt to connect automatically. The connection will be established once you
* call connect.
*
* @param serverUri the server URI to connect to
* @param protocolDraft The draft which should be used for this connection
* @param httpHeaders Additional HTTP-Headers
* @param connectTimeout The Timeout for the connection
*/
public WebSocketClient(URI serverUri, Draft protocolDraft, Map httpHeaders,
int connectTimeout) {
if (serverUri == null) {
throw new IllegalArgumentException();
} else if (protocolDraft == null) {
throw new IllegalArgumentException("null as draft is permitted for `WebSocketServer` only!");
}
this.uri = serverUri;
this.draft = protocolDraft;
this.dnsResolver = new DnsResolver() {
@Override
public InetAddress resolve(URI uri) throws UnknownHostException {
return InetAddress.getByName(uri.getHost());
}
};
if (httpHeaders != null) {
headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
headers.putAll(httpHeaders);
}
this.connectTimeout = connectTimeout;
setTcpNoDelay(false);
setReuseAddr(false);
this.engine = new WebSocketImpl(this, protocolDraft);
}
/**
* Returns the URI that this WebSocketClient is connected to.
*
* @return the URI connected to
*/
public URI getURI() {
return uri;
}
/**
* Returns the protocol version this channel uses.
For more infos see
* https://github.com/TooTallNate/Java-WebSocket/wiki/Drafts
*
* @return The draft used for this client
*/
public Draft getDraft() {
return draft;
}
/**
* Returns the socket to allow Hostname Verification
*
* @return the socket used for this connection
*/
public Socket getSocket() {
return socket;
}
/**
* @param key Name of the header to add.
* @param value Value of the header to add.
* @since 1.4.1 Adds an additional header to be sent in the handshake.
If the connection is
* already made, adding headers has no effect, unless reconnect is called, which then a new
* handshake is sent.
If a header with the same key already exists, it is overridden.
*/
public void addHeader(String key, String value) {
if (headers == null) {
headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
}
headers.put(key, value);
}
/**
* @param key Name of the header to remove.
* @return the previous value associated with key, or null if there was no mapping for key.
* @since 1.4.1 Removes a header from the handshake to be sent, if header key exists.
*/
public String removeHeader(String key) {
if (headers == null) {
return null;
}
return headers.remove(key);
}
/**
* @since 1.4.1 Clears all previously put headers.
*/
public void clearHeaders() {
headers = null;
}
/**
* Sets a custom DNS resolver.
*
* @param dnsResolver The DnsResolver to use.
* @since 1.4.1
*/
public void setDnsResolver(DnsResolver dnsResolver) {
this.dnsResolver = dnsResolver;
}
/**
* Reinitiates the websocket connection. This method does not block.
*
* @since 1.3.8
*/
public void reconnect() {
reset();
connect();
}
/**
* Same as reconnect
but blocks until the websocket reconnected or failed to do
* so.
*
* @return Returns whether it succeeded or not.
* @throws InterruptedException Thrown when the threads get interrupted
* @since 1.3.8
*/
public boolean reconnectBlocking() throws InterruptedException {
reset();
return connectBlocking();
}
/**
* Reset everything relevant to allow a reconnect
*
* @since 1.3.8
*/
private void reset() {
Thread current = Thread.currentThread();
if (current == writeThread || current == connectReadThread) {
throw new IllegalStateException(
"You cannot initialize a reconnect out of the websocket thread. Use reconnect in another thread to ensure a successful cleanup.");
}
try {
closeBlocking();
if (writeThread != null) {
this.writeThread.interrupt();
this.writeThread = null;
}
if (connectReadThread != null) {
this.connectReadThread.interrupt();
this.connectReadThread = null;
}
this.draft.reset();
if (this.socket != null) {
this.socket.close();
this.socket = null;
}
} catch (Exception e) {
onError(e);
engine.closeConnection(CloseFrame.ABNORMAL_CLOSE, e.getMessage());
return;
}
connectLatch = new CountDownLatch(1);
closeLatch = new CountDownLatch(1);
this.engine = new WebSocketImpl(this, this.draft);
}
/**
* Initiates the websocket connection. This method does not block.
*/
public void connect() {
if (connectReadThread != null) {
throw new IllegalStateException("WebSocketClient objects are not reuseable");
}
connectReadThread = new Thread(this);
connectReadThread.setName("WebSocketConnectReadThread-" + connectReadThread.getId());
connectReadThread.start();
}
/**
* Same as connect
but blocks until the websocket connected or failed to do so.
*
* @return Returns whether it succeeded or not.
* @throws InterruptedException Thrown when the threads get interrupted
*/
public boolean connectBlocking() throws InterruptedException {
connect();
connectLatch.await();
return engine.isOpen();
}
/**
* Same as connect
but blocks with a timeout until the websocket connected or failed
* to do so.
*
* @param timeout The connect timeout
* @param timeUnit The timeout time unit
* @return Returns whether it succeeded or not.
* @throws InterruptedException Thrown when the threads get interrupted
*/
public boolean connectBlocking(long timeout, TimeUnit timeUnit) throws InterruptedException {
connect();
return connectLatch.await(timeout, timeUnit) && engine.isOpen();
}
/**
* Initiates the websocket close handshake. This method does not block
In oder to make sure
* the connection is closed use closeBlocking
*/
public void close() {
if (writeThread != null) {
engine.close(CloseFrame.NORMAL);
}
}
/**
* Same as close
but blocks until the websocket closed or failed to do so.
*
* @throws InterruptedException Thrown when the threads get interrupted
*/
public void closeBlocking() throws InterruptedException {
close();
closeLatch.await();
}
/**
* Sends text to the connected websocket server.
*
* @param text The string which will be transmitted.
*/
public void send(String text) {
engine.send(text);
}
/**
* Sends binary data to the connected webSocket server.
*
* @param data The byte-Array of data to send to the WebSocket server.
*/
public void send(byte[] data) {
engine.send(data);
}
@Override
public T getAttachment() {
return engine.getAttachment();
}
@Override
public void setAttachment(T attachment) {
engine.setAttachment(attachment);
}
@Override
protected Collection getConnections() {
return Collections.singletonList((WebSocket) engine);
}
@Override
public void sendPing() {
engine.sendPing();
}
public void run() {
InputStream istream;
try {
boolean upgradeSocketToSSLSocket = prepareSocket();
socket.setTcpNoDelay(isTcpNoDelay());
socket.setReuseAddress(isReuseAddr());
if (!socket.isConnected()) {
InetSocketAddress addr = new InetSocketAddress(dnsResolver.resolve(uri), this.getPort());
socket.connect(addr, connectTimeout);
}
// if the socket is set by others we don't apply any TLS wrapper
if (upgradeSocketToSSLSocket && "wss".equals(uri.getScheme())) {
upgradeSocketToSSL();
}
if (socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket) socket;
SSLParameters sslParameters = sslSocket.getSSLParameters();
onSetSSLParameters(sslParameters);
sslSocket.setSSLParameters(sslParameters);
}
istream = socket.getInputStream();
ostream = socket.getOutputStream();
sendHandshake();
} catch (/*IOException | SecurityException | UnresolvedAddressException | InvalidHandshakeException | ClosedByInterruptException | SocketTimeoutException */Exception e) {
onWebsocketError(engine, e);
engine.closeConnection(CloseFrame.NEVER_CONNECTED, e.getMessage());
return;
} catch (InternalError e) {
// https://bugs.openjdk.java.net/browse/JDK-8173620
if (e.getCause() instanceof InvocationTargetException && e.getCause()
.getCause() instanceof IOException) {
IOException cause = (IOException) e.getCause().getCause();
onWebsocketError(engine, cause);
engine.closeConnection(CloseFrame.NEVER_CONNECTED, cause.getMessage());
return;
}
throw e;
}
writeThread = new Thread(new WebsocketWriteThread(this));
writeThread.start();
byte[] rawbuffer = new byte[WebSocketImpl.RCVBUF];
int readBytes;
try {
while (!isClosing() && !isClosed() && (readBytes = istream.read(rawbuffer)) != -1) {
engine.decode(ByteBuffer.wrap(rawbuffer, 0, readBytes));
}
engine.eot();
} catch (IOException e) {
handleIOException(e);
} catch (RuntimeException e) {
// this catch case covers internal errors only and indicates a bug in this websocket implementation
onError(e);
engine.closeConnection(CloseFrame.ABNORMAL_CLOSE, e.getMessage());
}
connectReadThread = null;
}
private void upgradeSocketToSSL()
throws NoSuchAlgorithmException, KeyManagementException, IOException {
SSLSocketFactory factory;
// Prioritise the provided socketfactory
// Helps when using web debuggers like Fiddler Classic
if (socketFactory instanceof SSLSocketFactory) {
factory = (SSLSocketFactory) socketFactory;
} else {
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
factory = sslContext.getSocketFactory();
}
socket = factory.createSocket(socket, uri.getHost(), getPort(), true);
}
private boolean prepareSocket() throws IOException {
boolean upgradeSocketToSSLSocket = false;
// Prioritise a proxy over a socket factory and apply the socketfactory later
if (proxy != Proxy.NO_PROXY) {
socket = new Socket(proxy);
upgradeSocketToSSLSocket = true;
} else if (socketFactory != null) {
socket = socketFactory.createSocket();
} else if (socket == null) {
socket = new Socket(proxy);
upgradeSocketToSSLSocket = true;
} else if (socket.isClosed()) {
throw new IOException();
}
return upgradeSocketToSSLSocket;
}
/**
* Apply specific SSLParameters If you override this method make sure to always call
* super.onSetSSLParameters() to ensure the hostname validation is active
*
* @param sslParameters the SSLParameters which will be used for the SSLSocket
*/
protected void onSetSSLParameters(SSLParameters sslParameters) {
// If you run into problem on Android (NoSuchMethodException), check out the wiki https://github.com/TooTallNate/Java-WebSocket/wiki/No-such-method-error-setEndpointIdentificationAlgorithm
// Perform hostname validation
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
}
/**
* Extract the specified port
*
* @return the specified port or the default port for the specific scheme
*/
private int getPort() {
int port = uri.getPort();
String scheme = uri.getScheme();
if ("wss".equals(scheme)) {
return port == -1 ? WebSocketImpl.DEFAULT_WSS_PORT : port;
} else if ("ws".equals(scheme)) {
return port == -1 ? WebSocketImpl.DEFAULT_PORT : port;
} else {
throw new IllegalArgumentException("unknown scheme: " + scheme);
}
}
/**
* Create and send the handshake to the other endpoint
*
* @throws InvalidHandshakeException a invalid handshake was created
*/
private void sendHandshake() throws InvalidHandshakeException {
String path;
String part1 = uri.getRawPath();
String part2 = uri.getRawQuery();
if (part1 == null || part1.length() == 0) {
path = "/";
} else {
path = part1;
}
if (part2 != null) {
path += '?' + part2;
}
int port = getPort();
String host = uri.getHost() + (
(port != WebSocketImpl.DEFAULT_PORT && port != WebSocketImpl.DEFAULT_WSS_PORT)
? ":" + port
: "");
HandshakeImpl1Client handshake = new HandshakeImpl1Client();
handshake.setResourceDescriptor(path);
handshake.put("Host", host);
if (headers != null) {
for (Map.Entry kv : headers.entrySet()) {
handshake.put(kv.getKey(), kv.getValue());
}
}
engine.startHandshake(handshake);
}
/**
* This represents the state of the connection.
*/
public ReadyState getReadyState() {
return engine.getReadyState();
}
/**
* Calls subclass' implementation of onMessage.
*/
@Override
public final void onWebsocketMessage(WebSocket conn, String message) {
onMessage(message);
}
@Override
public final void onWebsocketMessage(WebSocket conn, ByteBuffer blob) {
onMessage(blob);
}
/**
* Calls subclass' implementation of onOpen.
*/
@Override
public final void onWebsocketOpen(WebSocket conn, Handshakedata handshake) {
startConnectionLostTimer();
onOpen((ServerHandshake) handshake);
connectLatch.countDown();
}
/**
* Calls subclass' implementation of onClose.
*/
@Override
public final void onWebsocketClose(WebSocket conn, int code, String reason, boolean remote) {
stopConnectionLostTimer();
if (writeThread != null) {
writeThread.interrupt();
}
onClose(code, reason, remote);
connectLatch.countDown();
closeLatch.countDown();
}
/**
* Calls subclass' implementation of onIOError.
*/
@Override
public final void onWebsocketError(WebSocket conn, Exception ex) {
onError(ex);
}
@Override
public final void onWriteDemand(WebSocket conn) {
// nothing to do
}
@Override
public void onWebsocketCloseInitiated(WebSocket conn, int code, String reason) {
onCloseInitiated(code, reason);
}
@Override
public void onWebsocketClosing(WebSocket conn, int code, String reason, boolean remote) {
onClosing(code, reason, remote);
}
/**
* Send when this peer sends a close handshake
*
* @param code The codes can be looked up here: {@link CloseFrame}
* @param reason Additional information string
*/
public void onCloseInitiated(int code, String reason) {
//To overwrite
}
/**
* Called as soon as no further frames are accepted
*
* @param code The codes can be looked up here: {@link CloseFrame}
* @param reason Additional information string
* @param remote Returns whether or not the closing of the connection was initiated by the remote
* host.
*/
public void onClosing(int code, String reason, boolean remote) {
//To overwrite
}
/**
* Getter for the engine
*
* @return the engine
*/
public WebSocket getConnection() {
return engine;
}
@Override
public InetSocketAddress getLocalSocketAddress(WebSocket conn) {
if (socket != null) {
return (InetSocketAddress) socket.getLocalSocketAddress();
}
return null;
}
@Override
public InetSocketAddress getRemoteSocketAddress(WebSocket conn) {
if (socket != null) {
return (InetSocketAddress) socket.getRemoteSocketAddress();
}
return null;
}
// ABSTRACT METHODS /////////////////////////////////////////////////////////
/**
* Called after an opening handshake has been performed and the given websocket is ready to be
* written on.
*
* @param handshakedata The handshake of the websocket instance
*/
public abstract void onOpen(ServerHandshake handshakedata);
/**
* Callback for string messages received from the remote host
*
* @param message The UTF-8 decoded message that was received.
* @see #onMessage(ByteBuffer)
**/
public abstract void onMessage(String message);
/**
* Called after the websocket connection has been closed.
*
* @param code The codes can be looked up here: {@link CloseFrame}
* @param reason Additional information string
* @param remote Returns whether or not the closing of the connection was initiated by the remote
* host.
**/
public abstract void onClose(int code, String reason, boolean remote);
/**
* Called when errors occurs. If an error causes the websocket connection to fail {@link
* #onClose(int, String, boolean)} will be called additionally.
This method will be called
* primarily because of IO or protocol errors.
If the given exception is an RuntimeException
* that probably means that you encountered a bug.
*
* @param ex The exception causing this error
**/
public abstract void onError(Exception ex);
/**
* Callback for binary messages received from the remote host
*
* @param bytes The binary message that was received.
* @see #onMessage(String)
**/
public void onMessage(ByteBuffer bytes) {
//To overwrite
}
private class WebsocketWriteThread implements Runnable {
private final WebSocketClient webSocketClient;
WebsocketWriteThread(WebSocketClient webSocketClient) {
this.webSocketClient = webSocketClient;
}
@Override
public void run() {
Thread.currentThread().setName("WebSocketWriteThread-" + Thread.currentThread().getId());
try {
runWriteData();
} catch (IOException e) {
handleIOException(e);
} finally {
closeSocket();
writeThread = null;
}
}
/**
* Write the data into the outstream
*
* @throws IOException if write or flush did not work
*/
private void runWriteData() throws IOException {
try {
while (!Thread.interrupted()) {
ByteBuffer buffer = engine.outQueue.take();
ostream.write(buffer.array(), 0, buffer.limit());
ostream.flush();
}
} catch (InterruptedException e) {
for (ByteBuffer buffer : engine.outQueue) {
ostream.write(buffer.array(), 0, buffer.limit());
ostream.flush();
}
Thread.currentThread().interrupt();
}
}
/**
* Closing the socket
*/
private void closeSocket() {
try {
if (socket != null) {
socket.close();
}
} catch (IOException ex) {
onWebsocketError(webSocketClient, ex);
}
}
}
/**
* Method to set a proxy for this connection
*
* @param proxy the proxy to use for this websocket client
*/
public void setProxy(Proxy proxy) {
if (proxy == null) {
throw new IllegalArgumentException();
}
this.proxy = proxy;
}
/**
* Accepts bound and unbound sockets.
This method must be called before connect
.
* If the given socket is not yet bound it will be bound to the uri specified in the constructor.
*
* @param socket The socket which should be used for the connection
* @deprecated use setSocketFactory
*/
@Deprecated
public void setSocket(Socket socket) {
if (this.socket != null) {
throw new IllegalStateException("socket has already been set");
}
this.socket = socket;
}
/**
* Accepts a SocketFactory.
This method must be called before connect
. The socket
* will be bound to the uri specified in the constructor.
*
* @param socketFactory The socket factory which should be used for the connection.
*/
public void setSocketFactory(SocketFactory socketFactory) {
this.socketFactory = socketFactory;
}
@Override
public void sendFragmentedFrame(Opcode op, ByteBuffer buffer, boolean fin) {
engine.sendFragmentedFrame(op, buffer, fin);
}
@Override
public boolean isOpen() {
return engine.isOpen();
}
@Override
public boolean isFlushAndClose() {
return engine.isFlushAndClose();
}
@Override
public boolean isClosed() {
return engine.isClosed();
}
@Override
public boolean isClosing() {
return engine.isClosing();
}
@Override
public boolean hasBufferedData() {
return engine.hasBufferedData();
}
@Override
public void close(int code) {
engine.close(code);
}
@Override
public void close(int code, String message) {
engine.close(code, message);
}
@Override
public void closeConnection(int code, String message) {
engine.closeConnection(code, message);
}
@Override
public void send(ByteBuffer bytes) {
engine.send(bytes);
}
@Override
public void sendFrame(Framedata framedata) {
engine.sendFrame(framedata);
}
@Override
public void sendFrame(Collection frames) {
engine.sendFrame(frames);
}
@Override
public InetSocketAddress getLocalSocketAddress() {
return engine.getLocalSocketAddress();
}
@Override
public InetSocketAddress getRemoteSocketAddress() {
return engine.getRemoteSocketAddress();
}
@Override
public String getResourceDescriptor() {
return uri.getPath();
}
@Override
public boolean hasSSLSupport() {
return engine.hasSSLSupport();
}
@Override
public SSLSession getSSLSession() {
return engine.getSSLSession();
}
@Override
public IProtocol getProtocol() {
return engine.getProtocol();
}
/**
* Method to give some additional info for specific IOExceptions
*
* @param e the IOException causing a eot.
*/
private void handleIOException(IOException e) {
if (e instanceof SSLException) {
onError(e);
}
engine.eot();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy