This project is read-only.
1

Closed

为什么主程序无法捕获MessageReceived事件?

description

非常感谢您共享的代码,不过在应用中发现一个问题,使用过滤器logger和codec时,发现主程序无法捕获 acceptor.MessageReceived 事件。

acceptor.FilterChain.AddLast("logger", new LoggingFilter());
acceptor.FilterChain.AddLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Encoding.UTF8)));

acceptor.ExceptionCaught +=
(o, e) => Console.WriteLine(e.Exception);
acceptor.SessionIdle +=
(o, e) => Console.WriteLine("IDLE " + e.Session.GetIdleCount(e.IdleStatus));
acceptor.MessageReceived += (o, e) =>
{
String str = e.Message.ToString();

// "Quit" ? let's get out ...
if (str.Trim().Equals("quit", StringComparison.OrdinalIgnoreCase))
{
  e.Session.Close(true);
  return;
}
但是如果注释掉codec过滤器,则可以捕获。只是如果注释掉codec过滤器,则发送数据的时候会报错。请问这是什么原因呢?谢谢!!!

irvinghe

11716903@qq.com
Closed Mar 23, 2015 at 4:58 AM by longshine

comments

longshine wrote Mar 20, 2015 at 1:31 PM

你好~

是这样的,codec是用于充当协议转换器,在过滤器链中编码发送的数据和解码接收到的数据的。
在没有过滤器的时候,MessageReceived()中接收到的消息和session.Write()中发送的消息都是IoBuffer,这是Mina.NET的内置数据类型,用于表示字节数据。

而如果有codec等过滤器,它们会对数据进行转换,MessageReceived()中接收到的消息和session.Write()中发送的消息就可能不是IoBuffer而是别的数据了。

例如,例程中用到的TextLineCodecFactory是解析输入的字符串行,只有当接收到了回车换行符( \r\n)之后,才认为是一行输入完了,才会将这一行传给MessageReceived()事件。
同样,使用了TextLineCodecFactory之后,才能在session.Write()中直接输出字符串,否则,会出现无法发送字符串的异常,因为直接Write()的字符串在Mina.NET的内部并不知道要如何处理为IoBuffer。

longshine wrote Mar 20, 2015 at 1:33 PM

请对比 Example/EchoServer 和 Example/GettingStarted/TimeServer 两个例程
关于 codec 过滤器,请参阅 http://mina.apache.org/mina-project/userguide/ch9-codec-filter/ch9-codec-filter.html 抱歉目前还没有这部分的中文文档。

irvinghe wrote Mar 20, 2015 at 3:10 PM

非常感谢您的回复。我大概了解了codec的作用,不过还是有些疑惑:当我使用codec的时候,我该如何从主程序捕获串口收到的数据或者socket上面收到的数据。目前的情况时使用codec时acceptor.MessageReceived 无法触发

irvinghe wrote Mar 20, 2015 at 3:18 PM

我已找到原因,是结束符的问题,在此感谢!

longshine wrote Mar 23, 2015 at 4:57 AM

You're welcome.