В настоящее время я использую неблокирующий SocketChannel (Java 1.6) в качестве клиента для сервера Redis.Redis принимает команды в виде простого текста непосредственно через сокет, завершается CRLF и отвечает как, быстрый пример:
SEND: 'PING \ r \ n'
RECV:'+ PONG \ r \ n'
Redis также может возвращать огромные ответы (в зависимости от того, что вы запрашиваете) со многими разделами \ r \ n-завершенных данных, все как часть одного ответа.
Я использую стандартный while (socket.read ()> 0) {// append bytes} цикл для чтения байтов из сокета и повторной сборки их на стороне клиента вответить.
ПРИМЕЧАНИЕ. Я не использую Selector, я просто использую несколько клиентских SocketChannels на стороне клиента, подключенных к серверу, ожидающих обслуживания команд отправки / получения.
ЧтоЯ запутался в том, что контракт метода SocketChannel.read () в неблокирующем режиме, в частности, как узнать, когда сервер завершил отправку, и у меня есть весьсообщение.
У меня есть несколько способов защиты от слишком быстрого возвращения и предоставленияver шанс ответить, но я застрял на одном:
- Возможно ли когда-либо read () вернуть байты, затем при последующем возврате вызованет байтов, но при следующем последующем вызове снова возвращаются некоторые байты?
В принципе, могу ли я верить, что сервер отвечает мне, если я получил хотя бы 1 байт и в итоге прочитал () возвращает 0, тогда я знаю, что все готово, или, возможно, сервер просто занят и может выдавить еще несколько байтов, если я буду ждать и продолжать попытки?
Если это может продолжать посылать байты даже после того, как read () вернул 0 байтов (после предыдущих успешных чтений), тогда я понятия не имею, как определить, когда сервер завершил разговор со мной, и на самом деле запутался, как стиль java.io. *Коммуникации даже знали бы, когда сервер «готов».
Как вы, ребята, знаете, read никогда не возвращает -1, если соединение не разорвано и это стандартные долгоживущие соединения с БД, поэтому я не буду закрыватьи открытиеих по каждому запросу.
Я знаю, что популярным ответом (по крайней мере, на эти вопросы NIO) было посмотреть на Grizzly, MINA или Netty - если возможно, я бы очень хотел узнать, как все это работает всырое состояние перед принятием некоторых сторонних зависимостей.
Спасибо.
Бонусный вопрос:
Я изначально думал, что блокирующий SocketChannel будет способомпродолжайте с этим, поскольку я действительно не хочу, чтобы вызывающий абонент что-либо делал, пока я не обработал его команду и не дал бы ему ответ в любом случае.
Если это окажется лучшим способом, я немного запуталсявидя, что SocketChannel.read () блокирует до тех пор, пока не будет достаточно байтов для заполнения заданного буфера ... если не считать всего побитового чтения, я не могу понять, как на самом деле предполагается использовать это поведение по умолчанию... Я никогда не знаю размер точного ответа, возвращаемого с сервера, поэтому мои вызовы SocketChannel.read () всегда блокируются до истечения времени ожидания (после чего я завершаюя вижу, что содержимое находилось в буфере).
Я не совсем уверен, как правильно использовать метод блокировки, поскольку он всегда зависает при чтении.