2013-08-26 5 views
0

포트 통합 예제를 코드베이스에 적용하려고합니다. 내가 생각하는 문제는 서버가 종료되거나 클라이언트가 작업을 마칠 때까지 또는 더 구체적으로는 전체 파이프 라인이 항상 사용될 때까지 클라이언트 & 서버 사이에서 채널을 열어 두어야한다는 것입니다. 따라서 유니 파이러 처리기가 파이프 라인에서 제거 된 예제의 워크 플로가 작동하지 않습니다.영구 채널을 통한 포트 통합

포트 통합 예제에서 보았던 문제는 클라이언트가 각 요청에 매직 바이트를 보류하고 있었지만 서버 측 채널은 포트 통합 처리기를 제거했습니다. 메시지가 유효한 프로토콜 메시지로 결정되었습니다. 통합 처리기가 더 이상 메시지의 형식이 잘못된 마법 바이트를 사용하기 위해 파이프 라인에 없기 때문에 클라이언트의 접두사 magic 바이트가 포함 된 채널의 후속 메시지를 처리 ​​할 수 ​​없었습니다.

통일 처리기를 파이프 라인에 남겨 둠으로써이 문제를 해결할 수 있었지만 스니퍼가 프로토콜을 식별 할 때마다 프로토콜 처리기를 추가하고있었습니다. 파이프 라인은 채널 수명 동안 지속 되었기 때문에 동일한 핸들러를 반복해서 계속 추가했습니다. 이는 채널에 속성을 추가하여 파이프 라인에 항목을 다시 추가하지 않아도 해결하기 쉽습니다.

이제는 몇 가지 버퍼로 분할 된 메시지가 표시됩니다. 클라이언트가 2k 바이트를 두 개의 메시지로 나누어 보내는 경우. 첫 번째 메시지는 올바르게 스니핑되어 다음 처리기 (LengthFieldBasedFrameDecoder)로 전달됩니다. 모든 바이트를 가지고 있지 않으므로 나머지를 기다립니다. 다음 메시지가 파이프 라인에서 유니 파이를 제거 할 수 없기 때문에 바이트의 나머지 부분을 가져올 때 나는 다시 스니핑하고 sniff는 실패합니다.

동일한 문제를 해결하거나 더 좋은 방법이있을 수 있습니까?

UPDATE : 통합 자에서 마법 바이트의 소비 이동은

올바른 접근 방식처럼 보인다,하지만 여전히 문제가 계속 (또는 것 같다) 동적으로 파이프 라인을 변경하는 것은 작동하지 않는다는 것입니다 3 netty 4와 동일합니다. 3

내 클라이언트 프로토콜은 모든 요청을 식별하기 위해 바이트 순서가 앞에 있습니다. netty 3에서는 단순히 ChannelBuffer의 바이트를 건너 뛰고 unifier를 제거하고 적절한 프로토콜 처리를 추가하여 해당 요청을 처리했습니다. 같은 일이 모든 후속 요청에서 발생했으며 완벽하게 작동했습니다.

그러나 netty 4를 사용하면 마술 바이트를 먹는 파이프 라인에서 처리기를 제거한 후에 채널이 종료 될 때까지 지속되는 채널의 수명 동안 사라집니다. 그래서 파이프 라인/ChannelHandlerContext가 채널을 통과하는 각 메시지에 대해 새로운 것처럼 보일 때마다, 이것은 매번 재사용되며 이것이 문제가있는 곳이라고 생각합니다.

afaict, 이것은 파이프 라인의 이러한 유형의 동적 변경을 실제로는 어렵거나 불가능하게 만듭니다. 나는 각 요청의 첫 번째 N 바이트만을 소비하려고하지만, 여러 개의 ByteBuf로 분해 된 큰 요청은 모두 처음 N 바이트를 먹게 될 것이기 때문에 파이프 라인에 남겨 둘 수 없다.

업데이트 2 : 내가 지금보고 있어요 동작이 나는 후속 항목에서 언급 한 내용에 관한 생각 : how to manage a prefixed byte sequence which identifies your protocol

답변

1

포트 통일 예를 들어 클라이언트가 프로토콜을 전환 기대하지 않습니다.정말로 이것을 지원하려면 클라이언트가 "이 특정 프로토콜을 사용하여 끝났습니다. 다음 메시지는 다른 프로토콜을 사용할 수 있습니다."라고 말하게하는 메커니즘을 만들어야합니다. 그런 다음 PortUnificationServerHandler를 다시 설정해야합니다. 삭제 된 파이프 라인에 삽입 됨.

UPDATE :

다시 시나리오를 읽은 후, 나는 당신의 문제가 당신의 통일 핸들러가 "마법 바이트를"소비하는 것으로 생각합니다. 그렇게해서는 안됩니다. Netty 예제는 그렇지 않습니다. unifictaion 핸들러는 프로토콜을 결정하고, corrcet 핸들러 시퀀스를 설치하고 나간다. 새 처리기 시퀀스는 첫 번째 바이트 버퍼가 변경되지 않은 것을 확인해야합니다. 즉, 바이트를 소비하지 않아야합니다.

+0

클라이언트가 프로토콜을 전환하지 않습니다. 단순히 채널을 통해 두 번째 메시지를 보내는 것입니다. 그것의 비동기 RPC 클라이언트 - 서버. 첫 번째 RPC 교환은 두 개가 괜찮습니다. 두 번째는 유니 파이가 파이프 라인에 없거나 두 번째 요청이 크기가 너무 커서 여러 ByteBuf의 코드로 깨졌습니다. – Michael

+0

나는 지적해야합니다. 3.6.6에서 정확히 같은 설정이 잘 작동했다. 모든 일은 코드베이스를 netty로 옮기는 것입니다. 4 – Michael

+0

@Michael Ok,하지만 그것이 시나리오를 해석하는 방법입니다. –

관련 문제