接続を開き、サイトにクエリを実行し、ページ数を取得してから、NIO を使用してすべてのページを同時に取得するメソッドがあります。最初のクエリは を使用して実行されURLConnection
、完全に正常に動作します。NIO セレクターとチャンネルを使用しようとすると、次の 2 つの問題が発生します。
1) イテレータからキーを削除しないsize()
と、クエリの印刷と送信が無限ループで実行されます。キーを削除しようとすると、UnsupportedOperationsException が発生します。ばっ!
2) ソケットに書き込んだ後、OP_WRITE からチャネルを登録解除する必要がありますか? もしそうならchannel.register(selector, SelectionKey.OP_READ)
、書面への関心を取り除くために電話することはできますか?
public void test() throws IOException {
// create selector
Selector selector = Selector.open();
System.out.println("opened");
// get the number of pages
URL itemUrl = new URL(ITEM_URL);
URLConnection conn = itemUrl.openConnection();
conn.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
// out.write(getHeaderString(itemUrl));
out.write(new Query("", "Internal Hard Drives", false, false, true, false, -1, 7603, 1, 14, -1, "", "PRICE", 1).toString());
out.close();
JsonReader in = new JsonReader(new InputStreamReader(conn.getInputStream()));
JsonParser parser = new JsonParser();
JsonObject tempObj = (JsonObject) parser.parse(in);
Pages.setNumOfPages(getNumberOfIterations(tempObj.get("PaginationInfo")));
System.out.println("Pages: " + Pages.getNumOfPages());
// for each page, create a channel, attach to selector with interest in read
// typically this would be i <= Pages.getNumberOfPages but to troubleshoot, i'm limiting this to just once.
for (int i = 1; i <= 1; i++) {
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress(itemUrl.getHost(), 80));
channel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ);
}
selector.select();
Set<SelectionKey> sk = selector.keys();
while (!sk.isEmpty()) {
System.out.println(sk.size());
Iterator<SelectionKey> iterator = sk.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buf = ByteBuffer.allocate(8192);
channel.read(buf);
buf.flip();
Product p = parse(buf, Product.class);
if (p != null) {
finalItems.add(p);
System.out.println("Item added!");
key.cancel();
}
} else if (key.isWritable()) {
SocketChannel channel = (SocketChannel) key.channel();
System.out.println(itemUrl);
System.out.println(new Query("", "Internal Hard Drives", false, false, true,
false, -1, 7603, 1, 14, -1, "", "PRICE", 1).toString());
channel.write(ByteBuffer.wrap(new Query("", "Internal Hard Drives", false,
false, true, false, -1, 7603, 1, 14, -1, "", "PRICE", 1).toString()
.getBytes()));
}
}
selector.select();
sk = selector.keys();
}
}