(1). 概述
在前一小篇,剖析到,Playwright会通过Process Hold住进程,然后,通过:PipeTransport包裹着Process,代表:PipeTransport是一个与进程通信的中间层.
(2). Transport
最喜欢的一件事情就是看接口了,因为:接口代表了这个实现类的大概功能.
public interface Transport {
// 发送消息
void send(JsonObject message);
// 拉取消息
JsonObject poll(Duration timeout);
// 关闭
void close() throws IOException;
}
(3). PipeTransport构造器
public class PipeTransport implements Transport {
// **********************************************************
// 1. 创建阻塞队列
// 主要用于,当向浏览器发送消息以及浏览器回复消息时的载体.
// **********************************************************
private final BlockingQueue<JsonObject> incoming = new ArrayBlockingQueue<>(1000);
private final BlockingQueue<String> outgoing= new ArrayBlockingQueue<>(1000);
private final ReaderThread readerThread;
private final WriterThread writerThread;
private boolean isClosed;
PipeTransport(InputStream input, OutputStream output) {
DataInputStream in = new DataInputStream(new BufferedInputStream(input));
// **********************************************************
// 2. 创建读写线程,并启动.
// **********************************************************
readerThread = new ReaderThread(in, incoming);
readerThread.start();
writerThread = new WriterThread(output, outgoing);
writerThread.start();
} // end
public void send(JsonObject message) {
if (isClosed) {
throw new PlaywrightException("Playwright connection closed");
}
try {
// **************************************************************
// 3. 把对象消息转换成JSON字符串,并,插入到队列(BlockingQueue<String>)里.
// **************************************************************
outgoing.put(gson().toJson(message));
} catch (InterruptedException e) {
throw new PlaywrightException("Failed to send message", e);
}
} // end send
@Override
public JsonObject poll(Duration timeout) {
if (isClosed) {
throw new PlaywrightException("Playwright connection closed");
}
try {
// **************************************************************
// 4. 读取队列(BlockingQueue<JsonObject>)里的数据
// **************************************************************
JsonObject message = incoming.poll(timeout.toMillis(), TimeUnit.MILLISECONDS);
if (message == null && readerThread.exception != null) {
try {
close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
throw new PlaywrightException("Failed to read message from driver, pipe closed.", readerThread.exception);
}
return message;
} catch (InterruptedException e) {
throw new PlaywrightException("Failed to read message", e);
}
}// end poll
}
(4). 总结
PipeTransport的主要职责是:发送消息,拉取消息,但是,这两者都只是把数据塞到队列里,并没有看到与进程通信,原因在于:Playwright通过:ReaderThread和WriterThread进行了解藕.