MINA 프레임워크의 인코딩 및 패키지 분리 처리
15795 단어 android
서버에서 클라이언트가 보낸 메시지를 읽을 때AbstractPolling Io Processor에 있는read 방법을 실행합니다. 왜냐하면 이전에 MINA에 대한 원본 분석에서 모든 세션의 요청에 대해 실제 집행자는 Io Processor 대상이고read 방법에서 현재 Io 세션에 대응하는 Io Filter 책임 체인을 얻을 수 있기 때문입니다.이어서 책임체인의 FireMessage Received 방법을 사용하고 FireMessage Received에서는callNext Message Received 방법을 사용하며callNext Message Received 방법에서IoFilter의 메시지 Received 방법을 실행한다. 이 방법의 진정한 실현은Protocol CodecFilter에 있다. 그의 구체적인 실현을 살펴보자.
ProtocolCodecFilter$messageReceived()
public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
LOGGER.debug("Processing a MESSAGE_RECEIVED for session {}", session.getId());
if (!(message instanceof IoBuffer)) {
nextFilter.messageReceived(session, message);
return;
}
IoBuffer in = (IoBuffer) message;
ProtocolDecoder decoder = factory.getDecoder(session);
ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter);
// Loop until we don't have anymore byte in the buffer,
// or until the decoder throws an unrecoverable exception or
// can't decoder a message, because there are not enough
// data in the buffer
while (in.hasRemaining()) {
int oldPos = in.position();
try {
synchronized (session) {
// Call the decoder with the read bytes
decoder.decode(session, in, decoderOut);
}
// Finish decoding if no exception was thrown.
decoderOut.flush(nextFilter, session);
} catch (Exception e) {
ProtocolDecoderException pde;
if (e instanceof ProtocolDecoderException) {
pde = (ProtocolDecoderException) e;
} else {
pde = new ProtocolDecoderException(e);
}
if (pde.getHexdump() == null) {
// Generate a message hex dump
int curPos = in.position();
in.position(oldPos);
pde.setHexdump(in.getHexDump());
in.position(curPos);
}
// Fire the exceptionCaught event.
decoderOut.flush(nextFilter, session);
nextFilter.exceptionCaught(session, pde);
// Retry only if the type of the caught exception is
// recoverable and the buffer position has changed.
// We check buffer position additionally to prevent an
// infinite loop.
if (!(e instanceof RecoverableProtocolDecoderException) || (in.position() == oldPos)) {
break;
}
}
}
}
이 방법의 네 번째 줄은 현재 메시지가IoBuffer인지 아닌지를 먼저 판단합니다. 그렇지 않으면 nextFilter의 메시지 Received를 호출하여 다음 IoFilter에서 처리하고 현재 IoFilter 처리를 끝냅니다. 여기의nextFilter는 EntryImpl의 대상입니다. 그는DefaultIoFilterChain의 내부 클래스입니다.그의 메시지 Received 방법을 살펴보겠습니다.DefaultIoFilterChain#EntryImpl
public void messageReceived(IoSession session, Object message) {
Entry nextEntry = EntryImpl.this.nextEntry;
callNextMessageReceived(nextEntry, session, message);
}
실제로 호출된 것은callNextMessageReceived 메서드
callNextMessageReceived 메서드가 다시 호출됩니다.
IoFilter의 메시지 Received 방법은 현재의 메시지 대상이 IoBuffer인지 아닌지를 계속 판단한다. 지금까지는 간접적인 귀속 작업에 해당한다.
현재 메시지가IoBuffer라면 10줄에서 디코더 공장을 통해 디코더 Protocol Decoder를 얻을 수 있습니다. Protocol Decoder 인터페이스를 통해 디코더를 실현할 수 있습니다. 17줄에서 현재 IoBuffer에 디코더가 필요한 내용이 있는지 판단하고 존재하면 22줄의 디코더를 실행하는 방법입니다.만약 디코더가 우리 스스로 실현된다면 이 방법은 우리 스스로 실현될 것이다. 그리고 우리가 실현한 decode 방법으로 이 메시지를 디코딩한 후에Protocol Decoder Output의 write 방법을 호출하여 디코더된 정보를 대기열에 추가한다.
AbstractProtocolDecoderOutput$write()
public void write(Object message) {
if (message == null) {
throw new IllegalArgumentException("message");
}
messageQueue.add(message);
}
write 방법을 실행한 후Protocol Codec Filter $message Received () 의 25 줄에서 flush 방법을 실행했습니다. 이 방법은 현재 해석된 정보를 전달하고 다음 IoFilter에서 처리합니다. flush 방법의 구체적인 실현은 Protocol Codec Filter의 정적 내부 클래스인 Protocol Decoder Output Impl 안에 있습니다.
ProtocolDecoderOutputImpl$flush
public void flush(NextFilter nextFilter, IoSession session) {
Queue
사실 실행하는 방법은 넥스트Filter의 메시지 Received 방법입니다. 이렇게 계속 실행하면 책임체인의 끝부분인 TailFilter에 도달할 때까지TailFilter를 실행합니다.메시지 Received, 사실상 IoHandler를 실행합니다
메시지 Received 방법입니다. 이 방법에서 저희 업무 정보를 처리하면 됩니다.
이것이 바로 디코딩 과정입니다. 그러면 인코딩 과정은 어떤 모양입니까?실제로는 역방향 디코딩 과정이다.
클라이언트가 MINA를 통해 서버에 데이터를 전달하려면 먼저 IoSession 대상을 얻어 그의 write 방법을 실행해야 한다. 구체적인 실현은 AbstractIoSession에서 이루어진 것이다. write 방법에서 현재 IoSession에 대응하는 IoFilter 체인을 얻고 IoFilter 체인의 FireFilter Write 방법을 호출한다.실제로 실행된 것은DefaultIo Filter Chain 안의 Fire Filter Write 방법에서call Previous Filter Write 방법을 실행하고call Previous Filter Write에서Io Filter Write 방법을 실행한다. 이 방법은 우리가 말하고자 하는 중점이다. 그의 실현은Protocol Codec Filter 안에 있다.
ProtocolCodecFilter$filterWrite
public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
Object message = writeRequest.getMessage();
// Bypass the encoding if the message is contained in a IoBuffer,
// as it has already been encoded before
if ((message instanceof IoBuffer) || (message instanceof FileRegion)) {
nextFilter.filterWrite(session, writeRequest);
return;
}
// Get the encoder in the session
ProtocolEncoder encoder = factory.getEncoder(session);
ProtocolEncoderOutput encoderOut = getEncoderOut(session, nextFilter, writeRequest);
if (encoder == null) {
throw new ProtocolEncoderException("The encoder is null for the session " + session);
}
try {
// Now we can try to encode the response
encoder.encode(session, message, encoderOut);
// Send it directly
Queue
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.