package com.facebook.stetho.sample;
import com.facebook.stetho.inspector.network.NetworkEventReporter;
import com.facebook.stetho.inspector.network.NetworkEventReporterImpl;
import com.facebook.stetho.inspector.network.SimpleTextInspectorWebSocketFrame;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.annotation.Nullable;
/**
* Simple IRC client connection system to demonstrate Stetho's "websocket" (any arbitrary
* socket will work too) support.
*/
public class IRCClientConnection implements Closeable {
private final StethoReporter mReporter;
private final Socket mSocket;
private final BufferedReader mInput;
private final BufferedWriter mOutput;
public static IRCClientConnection connect(String host, int port) throws IOException {
StethoReporter reporter = new StethoReporter();
Socket socket = new Socket();
reporter.onPreConnect(host, port);
try {
socket.connect(new InetSocketAddress(host, port));
reporter.onPostConnect();
} catch (IOException e) {
reporter.onError(e);
try {
socket.close();
throw e;
} finally {
reporter.onClosed();
}
}
return new IRCClientConnection(reporter, socket, "UTF-8");
}
private IRCClientConnection(
StethoReporter reporter,
Socket socket,
String charset)
throws IOException {
mReporter = reporter;
mSocket = socket;
mInput = new BufferedReader(new InputStreamReader(socket.getInputStream(), charset));
mOutput = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), charset));
}
@Nullable
public String read() throws IOException {
try {
String message = mInput.readLine();
if (message != null) {
mReporter.onReceive(message);
maybeHandleIncomingMessage(message);
}
return message;
} catch (IOException e) {
mReporter.onError(e);
throw e;
}
}
public void send(String message) throws IOException {
mReporter.onSend(message);
try {
mOutput.write(message + "\r\n");
mOutput.flush();
} catch (IOException e) {
mReporter.onError(e);
throw e;
}
}
private boolean maybeHandleIncomingMessage(String message) throws IOException {
if (message.startsWith("PING ")) {
send("PONG " + message.substring("PING ".length()));
return true;
}
return false;
}
public void close() throws IOException {
try {
try {
mOutput.close();
} catch (IOException e) {
mReporter.onError(e);
throw e;
}
} finally {
try {
mSocket.close();
} catch (IOException e) {
mReporter.onError(e);
// Technically this should use addSuppressed but it's KITKAT only and this is a demo...
throw e;
} finally {
mReporter.onClosed();
}
}
}
private static class StethoReporter {
private final NetworkEventReporter mReporter;
private final String mRequestId;
public StethoReporter() {
mReporter = NetworkEventReporterImpl.get();
mRequestId = mReporter.nextRequestId();
}
public void onPreConnect(String host, int port) {
mReporter.webSocketCreated(mRequestId, "irc://" + host + ":" + port);
}
public void onPostConnect() {
// Sadly, nothing to report...
}
public void onError(IOException e) {
mReporter.webSocketFrameError(mRequestId, e.getMessage());
}
public void onClosed() {
mReporter.webSocketClosed(mRequestId);
}
public void onSend(String message) {
mReporter.webSocketFrameSent(new SimpleTextInspectorWebSocketFrame(mRequestId, message));
}
public void onReceive(String message) {
mReporter.webSocketFrameReceived(new SimpleTextInspectorWebSocketFrame(mRequestId, message));
}
}
}