You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Andrea Gariboldi <an...@gmail.com> on 2007/06/22 19:45:44 UTC
SocketAcceptor extensibility enhancement
Hi all,
i started using MINA-sm to write an smtp server, mostly
to learn using it. i would like to extend SocketSessionImpl
to add protocol specific fields without using setAttribute,
that seems to me an underperforming method.
Lets take my SMTP implementation as an example, so if
i'am wrong you can insult me ;)
I have an SmtpCommandDecoder that extends TextLineDecoder,
and normally writes out some Class<? extends SmtpCommand> instance..
BUT, when the session is receiving message body, lets say between a DATA
command and a <CRLF>.<CRLF>, it writes out directly the message string,
so actually is something like:
public class SmtpCommandDecoder extends TextLineDecoder {
.............
@Override
public void decode(final IoSession session, ByteBuffer in,
final ProtocolDecoderOutput out) throws Exception {
super.decode(session, in, new ProtocolDecoderOutput() {
public void write(Object message) {
if (session.containsAttribute(RECEIVING_DATA)) /*
<--------------LOOK HERE--------------------- */
{
if (endDataCommand.getName().equals(message))
out.write(endDataCommand);
else
out.write(message);
}
else
{
SmtpCommand cmd = parseCommand((String) message);
if (cmd != null)
{
if (cmd instanceof DataCommand)
session.setAttribute(RECEIVING_DATA, FLAG);
out.write(cmd);
}
}
}
private SmtpCommand parseCommand(String cmdLine) { ... }
...........
The highlighted instruction will be executed for each command for each
client session,
and actually wil search in a Map (BaseIoSession.attributes) the result. I
would like
to write something like:
1) solution one (not the best)
public void decode(final IoSession session, ByteBuffer in,
final ProtocolDecoderOutput out) throws Exception {
if (((SmtpSession)session).isReceivingData())
....
2) solution two (great)
public void decode(final SmtpSession session, ByteBuffer in,
final ProtocolDecoderOutput out) throws Exception {
if (session.isReceivingData())
I tried to implement solution 1 but:
1) The SocketAcceptor.newSession is not used:
public IoSession newSession( SocketAddress remoteAddress )
{
throw new UnsupportedOperationException();
}
instead the processSessions method does somenthing like:
SocketSessionImpl session = new SocketSessionImpl(...
2) SocketSessionImpl is not public
So my solution 1) patch proposal would be something like:
a) SocketAcceptor.newSession:
public IoSession newSession( SocketAddress remoteAddress )
{
throw new new SocketSessionImpl();
}
b) SocketAcceptor.processSessions:
private void processSessions( Set<SelectionKey> keys ) throws IOException
{
.................
SocketSession session = (SocketSession)newSession(null);
................
}
Solution 2, means use of generics, so no performance gains between solution
1)(casting) and 2)(generics)
but probably solution 2) means a lot of work.
now you can insult me. ;)
bye,
AAA
Re: SocketAcceptor extensibility enhancement
Posted by Maarten Bosteels <mb...@gmail.com>.
Hi Andrea,
What about storing one instance of SmtpSession as an attribute of IoSession
?
You could create and store the SmtpSession in IoHandler.sessionOpened
Your decoder would look like:
public void decode(final IoSession session, ByteBuffer in,
final ProtocolDecoderOutput out) throws Exception {
SmtpSession smtpSession = session.getAttribute("SMTP_SESSION");
decode(smtpSession, in, out);
}
public void decode(final SmtpSession session, ByteBuffer in,
final ProtocolDecoderOutput out) throws Exception {
if (session.isReceivingData()) {
...
}
Maarten
On 6/22/07, Andrea Gariboldi <an...@gmail.com> wrote:
>
> Hi all,
> i started using MINA-sm to write an smtp server, mostly
> to learn using it. i would like to extend SocketSessionImpl
> to add protocol specific fields without using setAttribute,
> that seems to me an underperforming method.
>
> Lets take my SMTP implementation as an example, so if
> i'am wrong you can insult me ;)
>
> I have an SmtpCommandDecoder that extends TextLineDecoder,
> and normally writes out some Class<? extends SmtpCommand> instance..
> BUT, when the session is receiving message body, lets say between a DATA
> command and a <CRLF>.<CRLF>, it writes out directly the message string,
> so actually is something like:
>
> public class SmtpCommandDecoder extends TextLineDecoder {
> .............
>
> @Override
> public void decode(final IoSession session, ByteBuffer in,
> final ProtocolDecoderOutput out) throws Exception {
>
> super.decode(session, in, new ProtocolDecoderOutput() {
> public void write(Object message) {
> if (session.containsAttribute(RECEIVING_DATA)) /*
> <--------------LOOK HERE--------------------- */
> {
> if (endDataCommand.getName().equals(message))
> out.write(endDataCommand);
> else
> out.write(message);
> }
> else
> {
> SmtpCommand cmd = parseCommand((String) message);
> if (cmd != null)
> {
> if (cmd instanceof DataCommand)
> session.setAttribute(RECEIVING_DATA,
> FLAG);
>
> out.write(cmd);
> }
> }
> }
>
> private SmtpCommand parseCommand(String cmdLine) { ... }
>
> ...........
>
>
>
> The highlighted instruction will be executed for each command for each
> client session,
> and actually wil search in a Map (BaseIoSession.attributes) the result. I
> would like
> to write something like:
>
> 1) solution one (not the best)
>
> public void decode(final IoSession session, ByteBuffer in,
> final ProtocolDecoderOutput out) throws Exception {
>
> if (((SmtpSession)session).isReceivingData())
> ....
>
> 2) solution two (great)
>
> public void decode(final SmtpSession session, ByteBuffer in,
> final ProtocolDecoderOutput out) throws Exception {
>
> if (session.isReceivingData())
>
>
>
> I tried to implement solution 1 but:
>
> 1) The SocketAcceptor.newSession is not used:
>
> public IoSession newSession( SocketAddress remoteAddress )
> {
> throw new UnsupportedOperationException();
> }
>
> instead the processSessions method does somenthing like:
>
> SocketSessionImpl session = new SocketSessionImpl(...
>
> 2) SocketSessionImpl is not public
>
> So my solution 1) patch proposal would be something like:
>
> a) SocketAcceptor.newSession:
>
> public IoSession newSession( SocketAddress remoteAddress )
> {
> throw new new SocketSessionImpl();
> }
>
>
> b) SocketAcceptor.processSessions:
>
> private void processSessions( Set<SelectionKey> keys ) throws IOException
> {
> .................
> SocketSession session = (SocketSession)newSession(null);
> ................
> }
>
> Solution 2, means use of generics, so no performance gains between
> solution
> 1)(casting) and 2)(generics)
> but probably solution 2) means a lot of work.
>
>
> now you can insult me. ;)
>
> bye,
> AAA
>