Re: STOMP and JMSType
On 6/13/06, Nathan Mittler [EMAIL PROTECTED] wrote: So it sounds like we're all in agreement on the content-type header. For text, it would be something like text There could be a few values of Content-type which map to text (text/xml, application/soap, application/xml etc). Incidentally the default implementation for sending an ObjectMessage / MapMessage to a Stomp client could be to use XStream to turn it into XML and mark it as text/xml. Otherwise its gonna be extremely hard for a typical Stomp client to read the message. and for bytes it would be application/octet-stream. So this would not be an application-level header, but would be used by my stomp client code to determine which message type to create. If we're all in agreement with that, then it seems to make sense that the default functionality of the broker be modified to handle content-type in this way. And if that's true, then it seems like this particular issue is resolved. This way, we get it into the 4.1 release with no problems. We can create another issue to do the refactoring as you've suggested ... which will probably take a little more time and several conversations to get right. How does this sound? Sounds great. -- James --- http://radio.weblogs.com/0112098/
Re: STOMP and JMSType
On 6/14/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 13, 2006, at 3:06 PM, Nathan Mittler wrote: So it sounds like we're all in agreement on the content-type header. For text, it would be something like text and for bytes it would be application/octet-stream. So this would not be an application-level header, but would be used by my stomp client code to determine which message type to create. Content-type is application level. I was suggesting it for your use case where you want to know what to convert a bytes message into in your C++ library =) Agreed! the app in this use case is the C++ client lib. so the c++ client lib could set the content-type to control a custom transformer so that sent JMS messages are exactly as the C++ stomp lib wants them to look like. So I'm starting to think there are 2 main use cases: 1) I want to have portable STOMP client that work on other providers. Then you accept that you can not tightly integrate with an existing JMS network in a portable way. For example they would not be able to send and receive JMS Map messages. Since stomp does not specify what those messages would look like on the wire. This means that STOMP needs to define how a portable mapping of JMS ByteMessage and TextMessage to STOMP Messages. I think what we have today is very close to this. We may just need to formalize it a little more in a document so that other providers could implement the same STOMP to JMS mapping. Of course, this mapping has to stay simple. 2) You have a STOMP client that does not mind intimately knowing about ActiveMQ. Then it can request transformation on the the send and receives. That transformation could totally change all the STOMP rules about the headers for for the messages coming in and out. It might use the content-type to hold the JMS message type: bytes, text, object, map, etc. and other headers like jms.Type to hold the JMSType headers. Also the payload encoding could be fancier. So by default, I think it should work like case #1, if you want to use case#2, then you use the transform header options. This gives us backward compatibility but for your C++ stomp client that exposes a JMS like API use case, I would think it falls under use case #2. Also, as offshoot idea on #2, is a provider allowed able to expose additional verbs/operations to clients? Kinda like how SVN/DAV does for HTTP? If we're all in agreement with that, then it seems to make sense that the default functionality of the broker be modified to handle content- type in this way. No. activemq-transformer would provide the JMS type mapping to override the default. I suggested that you use content-type (not required by stomp) to decide if something is text or a byte stream. Transfer-encoding is also useful for this. :-) And if that's true, then it seems like this particular issue is resolved. This way, we get it into the 4.1 release with no problems. We can create another issue to do the refactoring as you've suggested ... which will probably take a little more time and several conversations to get right. How does this sound? Nate On 6/13/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 13, 2006, at 1:50 PM, Nathan Mittler wrote: Could you guys point me to a place in AMQ where this sort of thing is being done? That would save me a lot of searching =) I'm viewing this problem from the client side - the Stomp C++ client that Tim Bish and I are writing currently supports text and bytes messages. Within a general Stomp client, I would suggest that switching on JMS message types is not a productive goal. Using Content-type here makes a lot more sense, I think. . It would make a lot of sense to set it for text messages going out to Stomp if there is not one already supplied. Stomp is a protocol, like HTTP or SMTP -- hardwiring a client to a specific server implementation is probably not a general solution (though is fine if it is specifically an activemq client which happens to use stomp for transport). So when I get a stomp frame in, I need to map it back to a text or bytes message. We chose to do this for a couple of reasons: 1) to give JMS users a familiar interface and 2) to provide a simple interface for reading and writing text messages (e.g. xml). Content-type: text/xml -- Content-type: application/octet-stream With that said, I'm not seeing how I can do that mapping if the transformer is provided only in the SUBSCRIBE. A client could potentially get a variety of message types from a single subscription. I think it would have to be part of the MESSAGE frame, rather than the SUBSCRIBE. SUBSCRIBE activemq-transformer: com.example.ContentTypeMapper Here are the use cases I see: s/transformer/activemq-transformer/g I like the namespace. Client-Server 1) SEND\n...\ntransformer:text (client tells server it's a text message) +1 2)
Re: STOMP and JMSType
On 6/14/06, Mittler, Nathan [EMAIL PROTECTED] wrote: -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Hiram Chirino Sent: Wednesday, June 14, 2006 12:40 PM To: activemq-dev@geronimo.apache.org Subject: Re: STOMP and JMSType On 6/14/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 13, 2006, at 3:06 PM, Nathan Mittler wrote: So it sounds like we're all in agreement on the content-type header. For text, it would be something like text and for bytes it would be application/octet-stream. So this would not be an application-level header, but would be used by my stomp client code to determine which message type to create. Content-type is application level. I was suggesting it for your use case where you want to know what to convert a bytes message into in your C++ library =) Agreed! the app in this use case is the C++ client lib. so the c++ client lib could set the content-type to control a custom transformer so that sent JMS messages are exactly as the C++ stomp lib wants them to look like. Ok, so application-level is referring to the C++ library, not the user of the library? If so that eliminates the need for another header like amq-msg-type. How do we make this become part of the stomp spec? When we do, we should define the list of valid values for it (e.g. text and bytes). So here's a link to everything that is in the spec currently: http://stomp.codehaus.org/Protocol It's a WIKI so you can edit it and improve the spec. I think that a the big missing piece in the spec is that there is no specification of how STOMP messages get mapped to JMS messages. Since this is missing, there is no provider independent way of sending JMS messages from STOMP. Since every implementation could map a STOMP message to JMS messages differently. I think we need to add a STOMP Message to JMS Message Mapping section that providers SHOULD comply with if the provider also implements a JMS interface. The great part is since this is missing, you can make this whatever you want! So I'm starting to think there are 2 main use cases: 1) I want to have portable STOMP client that work on other providers. Then you accept that you can not tightly integrate with an existing JMS network in a portable way. For example they would not be able to send and receive JMS Map messages. Since stomp does not specify what those messages would look like on the wire. This means that STOMP needs to define how a portable mapping of JMS ByteMessage and TextMessage to STOMP Messages. I think what we have today is very close to this. We may just need to formalize it a little more in a document so that other providers could implement the same STOMP to JMS mapping. Of course, this mapping has to stay simple. 2) You have a STOMP client that does not mind intimately knowing about ActiveMQ. Then it can request transformation on the the send and receives. That transformation could totally change all the STOMP rules about the headers for for the messages coming in and out. It might use the content-type to hold the JMS message type: bytes, text, object, map, etc. and other headers like jms.Type to hold the JMSType headers. Also the payload encoding could be fancier. So by default, I think it should work like case #1, if you want to use case#2, then you use the transform header options. This gives us backward compatibility but for your C++ stomp client that exposes a JMS like API use case, I would think it falls under use case #2. So right now, I'm just concerned with #1. I'd like to make the first crack at our client as STOMP vendor independent as possible ... and we're only doing text and bytes messages for the first cut. Ok great! If we're in agreement that the two use cases you've identified are two separate JIRA issues, then we can just create a second JIRA for #2, and I can go off and implement #1 in the broker. Sure! BTW, what is the timeframe for 4.1? I like to aim for 1 month, and accept slipping a month or two :) I would say it's mostly dependent on new feature progress and code stability. Also, as offshoot idea on #2, is a provider allowed able to expose additional verbs/operations to clients? Kinda like how SVN/DAV does for HTTP? If we're all in agreement with that, then it seems to make sense that the default functionality of the broker be modified to handle content- type in this way. No. activemq-transformer would provide the JMS type mapping to override the default. I suggested that you use content-type (not required by stomp) to decide if something is text or a byte stream. Transfer-encoding is also useful for this. :-) And if that's true, then it seems like this particular issue is resolved. This way, we get it into the 4.1 release with no problems. We can create another issue to do the refactoring as you've suggested ... which
Re: STOMP and JMSType
I think that clears things up for me a bit - what you're proposing makes sense. I'll poke around today and see what I can come up with. Thanks, Nate On 6/12/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 12, 2006, at 4:14 PM, Nathan Mittler wrote: Agreed ... using the type header is not an option. --- From the bug report --- It isn't possible to reuse the type header (JMSType) for the purpose of sending through the information as to what type of message it is (text or bytes). So this means that we need to add another activemq extension header. I propose amq-msg-type. --- / From the bug report -- I like this a lot better, and think it would be a reasonable default rule for mapping in 4.X. I am not convinced we need this, but I much prefer it to a hardcoded transform, as this would allow for much more useful transforms (ie, aplication-aware). Although I agree conceptually, I'm thinking this might be a bit of an overkill for the task at hand. Agreed. I just hate to layer on another backwards compatibility issue beyond what we already have. By designing it to be forward compatible with an arbitrary mapping we can grow into a future solution more easily. Once we add this header we will need to support it ~forever. Right now the STOMP transport only works with bytes and text messages, and creating this transform model won't change that. I think if we one day decide to refactor the transport to accept other message types - that would be the time to make this sort of change. What if I want to switch on Content-type to decide between text or bytes? It is a common header to use, but is not part of the spec (as stomp doesn;t care, but is happy to pass it along). This makes more sense to me in terms of mapping between Stomp and JMS, but it is not compatible with switching on a specific content header. The mapping between Stomp and JMS is actually rather important to get right as it is the low level interop mapping between various platforms and Java. As such, I want to make sure we are building towards a correct solution. Aside from all this, controlling the protocol -- (semi-)protocol mapping should be a configuration thing, not a flag the client must put on every message it sends. The end goal for me is to have all messages coming in from the Stomp adaptor be bytes messages, unless someone has an overriding need for something else (quote possible). The current behavior is pretty bad as a default, but we just released 4.0 with it, so we are stuck until we make another backwards incompatible release (5.0). In 4.1 we can add the amq-msg-type header to allow people to force things to bytes (or text) but for the 5.0 end game we will need to make the mapping pluggable in order to make the upgrade path as easy as possible. if we are going to need pluggable eventually, why not do it now in order to allow people to fix the bytes/text mistake (I can say it is a mistake, I wrote it =) at the server level instead of having to add a header to every message. We have, then, three configurations which people are likely to want: 1) Current (3.2 and 4.0 compatible) one which is made more palatable by letting the client specify via the amq-msg-type. 2) Map everything to bytes, which I would like to make the default in 5.0. 3) Map everything to Text (which is what I would actually use if we had it as I convert all the bytes ones I send now into strings anyway). If we are going to have it be sufficiently pluggable to support these three, we should consider letting users provide their own. -Brian
Re: STOMP and JMSType
FWIW I'd like to have content-type header support. Couldn't we then use content-type as the standard header that any Stomp-JMS bridge would use to decide if something is a TextMessage or a BytesMessage? On 6/13/06, Nathan Mittler [EMAIL PROTECTED] wrote: I think that clears things up for me a bit - what you're proposing makes sense. I'll poke around today and see what I can come up with. Thanks, Nate On 6/12/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 12, 2006, at 4:14 PM, Nathan Mittler wrote: Agreed ... using the type header is not an option. --- From the bug report --- It isn't possible to reuse the type header (JMSType) for the purpose of sending through the information as to what type of message it is (text or bytes). So this means that we need to add another activemq extension header. I propose amq-msg-type. --- / From the bug report -- I like this a lot better, and think it would be a reasonable default rule for mapping in 4.X. I am not convinced we need this, but I much prefer it to a hardcoded transform, as this would allow for much more useful transforms (ie, aplication-aware). Although I agree conceptually, I'm thinking this might be a bit of an overkill for the task at hand. Agreed. I just hate to layer on another backwards compatibility issue beyond what we already have. By designing it to be forward compatible with an arbitrary mapping we can grow into a future solution more easily. Once we add this header we will need to support it ~forever. Right now the STOMP transport only works with bytes and text messages, and creating this transform model won't change that. I think if we one day decide to refactor the transport to accept other message types - that would be the time to make this sort of change. What if I want to switch on Content-type to decide between text or bytes? It is a common header to use, but is not part of the spec (as stomp doesn;t care, but is happy to pass it along). This makes more sense to me in terms of mapping between Stomp and JMS, but it is not compatible with switching on a specific content header. The mapping between Stomp and JMS is actually rather important to get right as it is the low level interop mapping between various platforms and Java. As such, I want to make sure we are building towards a correct solution. Aside from all this, controlling the protocol -- (semi-)protocol mapping should be a configuration thing, not a flag the client must put on every message it sends. The end goal for me is to have all messages coming in from the Stomp adaptor be bytes messages, unless someone has an overriding need for something else (quote possible). The current behavior is pretty bad as a default, but we just released 4.0 with it, so we are stuck until we make another backwards incompatible release (5.0). In 4.1 we can add the amq-msg-type header to allow people to force things to bytes (or text) but for the 5.0 end game we will need to make the mapping pluggable in order to make the upgrade path as easy as possible. if we are going to need pluggable eventually, why not do it now in order to allow people to fix the bytes/text mistake (I can say it is a mistake, I wrote it =) at the server level instead of having to add a header to every message. We have, then, three configurations which people are likely to want: 1) Current (3.2 and 4.0 compatible) one which is made more palatable by letting the client specify via the amq-msg-type. 2) Map everything to bytes, which I would like to make the default in 5.0. 3) Map everything to Text (which is what I would actually use if we had it as I convert all the bytes ones I send now into strings anyway). If we are going to have it be sufficiently pluggable to support these three, we should consider letting users provide their own. -Brian -- James --- http://radio.weblogs.com/0112098/
Re: STOMP and JMSType
I agree with all that. In a pure Stomp world, content-type is a very useful header and probably affect how the stomp client processes the message. Whatever the default rule is for Stomp - JMS I'd have thought most JMS providers would (through configuration or implementation) probably use that to make a sensible choice over Text v Bytes - even if it may break backward compatibility. (It should be trivial to configure backwards compatibility - everything is BytesMessage if folks really care) On 6/13/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 13, 2006, at 8:11 AM, Mittler, Nathan wrote: James, I think that's what we're proposing here. I proposed amq-msg-type, but I suppose content-type is just as good. I think Brian's main concern (Brian, correct me if I'm wrong) is that he'd like the mapping of stomp message to AMQ message type to be pluggable, not hard-coded. Actually, my first choice would be hard coded to bytes message, period, finished =) We cannot do this without breaking backwards compatibility, which I have been presuming we don't want to do. The most important thing, to me, when mapping from Stomp to JMS is to have it be very predictable. I don't want to ever have someone have a JMS client listening for stuff from Stomp and having to guess at the message type. As such, the default should be it is X. If they need some other mapping, I would suggest that they look at some kind of transformer service which republishes messages. If we are going to have more complicated mapping, I want to either make it super crippled: a default compatibility mode and a strong recommended 5.0 mode. The next step is to make mapping pluggable, but don't make a big deal out of it. As ben Laurie would say, a European style API. That is the external point of view. For the internal point of view, the cleanest implementation I can think of is to have an interface which takes a Send (or something like) and returns an ActiveMQMessage. I am quite strongly against using using application level metadata (which content-type is in Stomp and JMSType is in JMS) for mapping information. I am also quite against every client having to specify what to map the message to as the client should be able to be independent of the particular implementation. I think it is a very bad idea to require the client to add the mapping to every message. -Brian So if a user wanted to, they could configure the broker to turn all stomp messages into bytes messages, rather than using the default behavior of handling text and bytes messages differently. I guess I'm just not sure yet what this pluggable infrastructure should look like, as I don't think there is currently a framework in place. I already have a build with the hard-coded approach that is backward compatible with clients that don't use the amq-msg-type header. I guess I'll leave this as a question of what should be done: 1) submit what I've got (the hard-coded approach), once it's verified to be working. 2) step back and create a pluggable framework. Regards, Nate -Original Message- From: James Strachan [mailto:[EMAIL PROTECTED] Sent: Tuesday, June 13, 2006 10:57 AM To: activemq-dev@geronimo.apache.org Subject: Re: STOMP and JMSType FWIW I'd like to have content-type header support. Couldn't we then use content-type as the standard header that any Stomp-JMS bridge would use to decide if something is a TextMessage or a BytesMessage? On 6/13/06, Nathan Mittler [EMAIL PROTECTED] wrote: I think that clears things up for me a bit - what you're proposing makes sense. I'll poke around today and see what I can come up with. Thanks, Nate On 6/12/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 12, 2006, at 4:14 PM, Nathan Mittler wrote: Agreed ... using the type header is not an option. --- From the bug report --- It isn't possible to reuse the type header (JMSType) for the purpose of sending through the information as to what type of message it is (text or bytes). So this means that we need to add another activemq extension header. I propose amq-msg-type. --- / From the bug report -- I like this a lot better, and think it would be a reasonable default rule for mapping in 4.X. I am not convinced we need this, but I much prefer it to a hardcoded transform, as this would allow for much more useful transforms (ie, aplication-aware). Although I agree conceptually, I'm thinking this might be a bit of an overkill for the task at hand. Agreed. I just hate to layer on another backwards compatibility issue beyond what we already have. By designing it to be forward compatible with an arbitrary mapping we can grow into a future solution more easily. Once we add this header we will need to support it ~forever. Right now the STOMP transport only works with bytes and text messages, and creating this transform model won't change that. I think if we one day decide to refactor the transport
RE: STOMP and JMSType
Sounds good to me. +1 -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Hiram Chirino Sent: Tuesday, June 13, 2006 1:45 PM To: activemq-dev@geronimo.apache.org Subject: Re: STOMP and JMSType On 6/13/06, Mittler, Nathan [EMAIL PROTECTED] wrote: Just to make clear what the proposed new hard-coded logic does: 1) If there is no content-length, it's a text message (same as before) 2) else, if there is no message type, it's a bytes message (same as before) 3) else use amq-msg-type to determine the message type So this logic is backward-compatible with the existing logic. If the client does not specify amq-msg-type, the behavior will be the same as it is now. The STOMP protocol doesn't define a mapping to a JMS system, so as far as predictability goes, the users just need to follow our logic for the mapping. They wouldn't be able to change the mapping, like they would with a pluggable framework, but they shouldn't need to. They just code their clients against the mapping that we publish online and they'll be up and running. I'm getting the feeling that the main reason for leaning toward the pluggable framework is to support a BytesMessage-only paradigm. In a STOMP-only world this probably makes sense. You're just and receiving stuff. But when you're bridging between Stomp and JMS, I'm not sure why a client would ever want this restriction. It seems like if you want BytesMessages to come out the other end, then you just follow our mapping logic to make that happen, which really is as simple as including content-length (which you would have to include for a true bytes message anyway) and leave off amq-msg-type (which you would by default). Even if you were to implement a pluggable framework, you would still need to have some sort of application metadata like the amq-msg-type header. Assuming our framework is comprised of a bunch of message transformers that go between raw bytes and ActiveMQMessages, the default transformer for the STOMP transport would do this mapping the way I've proposed above. So you wouldn't be eliminating the need for the amq-msg-type header, you'd just be pushing around the logic that uses it. So I guess I'm still not seeing the bang for the buck ... it seems like the hard-coded solution works for all cases that we've defined so far. I'd rather just get this functionality in because I think it's useful and people have been asking for it. I'm all for continuing to discuss the pluggable framework, but it seems that that is a separate issue from what I'm trying to do here (...and probably literally a separate JIRA issue). I agree. But instead calling the header 'amq-msg-type' (which does not explicitly convey that a transformation is being used), I'd like it to be called 'activemq-transformation' set to a class name of the transformation (or something that maps to a classname, like we do for our service discovery). and this would be header that is not carried with the message, it's a header that controls the send and subscribe operations. Regards, Nate -Original Message- From: Brian McCallister [mailto:[EMAIL PROTECTED] Sent: Tuesday, June 13, 2006 12:20 PM To: activemq-dev@geronimo.apache.org Subject: Re: STOMP and JMSType On Jun 13, 2006, at 8:11 AM, Mittler, Nathan wrote: James, I think that's what we're proposing here. I proposed amq-msg-type, but I suppose content-type is just as good. I think Brian's main concern (Brian, correct me if I'm wrong) is that he'd like the mapping of stomp message to AMQ message type to be pluggable, not hard-coded. Actually, my first choice would be hard coded to bytes message, period, finished =) We cannot do this without breaking backwards compatibility, which I have been presuming we don't want to do. The most important thing, to me, when mapping from Stomp to JMS is to have it be very predictable. I don't want to ever have someone have a JMS client listening for stuff from Stomp and having to guess at the message type. As such, the default should be it is X. If they need some other mapping, I would suggest that they look at some kind of transformer service which republishes messages. If we are going to have more complicated mapping, I want to either make it super crippled: a default compatibility mode and a strong recommended 5.0 mode. The next step is to make mapping pluggable, but don't make a big deal out of it. As ben Laurie would say, a European style API. That is the external point of view. For the internal point of view, the cleanest implementation I can think of is to have an interface which takes a Send (or something like) and returns an ActiveMQMessage. I am quite strongly against using using application level metadata (which content-type is in Stomp and JMSType is in JMS) for mapping information. I am also quite against every client having to specify what to map the message
Re: STOMP and JMSType
I would suggest that we use a weak form of specification encoding. ActiveMQ already uses pseudo-urls in a lot of places, and named transforms trump class names, usually: yeah! URI style configuration rocks! -Brian -- Regards, Hiram
Re: STOMP and JMSType
So it sounds like we're all in agreement on the content-type header. For text, it would be something like text and for bytes it would be application/octet-stream. So this would not be an application-level header, but would be used by my stomp client code to determine which message type to create. If we're all in agreement with that, then it seems to make sense that the default functionality of the broker be modified to handle content-type in this way. And if that's true, then it seems like this particular issue is resolved. This way, we get it into the 4.1 release with no problems. We can create another issue to do the refactoring as you've suggested ... which will probably take a little more time and several conversations to get right. How does this sound? Nate On 6/13/06, Brian McCallister [EMAIL PROTECTED] wrote: On Jun 13, 2006, at 1:50 PM, Nathan Mittler wrote: Could you guys point me to a place in AMQ where this sort of thing is being done? That would save me a lot of searching =) I'm viewing this problem from the client side - the Stomp C++ client that Tim Bish and I are writing currently supports text and bytes messages. Within a general Stomp client, I would suggest that switching on JMS message types is not a productive goal. Using Content-type here makes a lot more sense, I think. . It would make a lot of sense to set it for text messages going out to Stomp if there is not one already supplied. Stomp is a protocol, like HTTP or SMTP -- hardwiring a client to a specific server implementation is probably not a general solution (though is fine if it is specifically an activemq client which happens to use stomp for transport). So when I get a stomp frame in, I need to map it back to a text or bytes message. We chose to do this for a couple of reasons: 1) to give JMS users a familiar interface and 2) to provide a simple interface for reading and writing text messages (e.g. xml). Content-type: text/xml -- Content-type: application/octet-stream With that said, I'm not seeing how I can do that mapping if the transformer is provided only in the SUBSCRIBE. A client could potentially get a variety of message types from a single subscription. I think it would have to be part of the MESSAGE frame, rather than the SUBSCRIBE. SUBSCRIBE activemq-transformer: com.example.ContentTypeMapper Here are the use cases I see: s/transformer/activemq-transformer/g I like the namespace. Client-Server 1) SEND\n...\ntransformer:text (client tells server it's a text message) +1 2) SEND\n...\ntransformer:bytes (client tells server it's a bytes message) +1 3) SEND\n...\ntransformer:default (client tells server to use content-length to make determination) -1 Give it a descriptive name so that we can change the default without breaking these. 4) SEND\n...\n (no transformer specified - same as #3) +1 5) SEND\n..\ntransformer:bob (client gives server unknown transformer - use default) Return an error -- do not quietly swallow this. Server-Client 1) MESSAGE\n...\ntransformer:text (server tells client it's a text message) +1 2) MESSAGE\n...\ntransformer:bytes (server tells client it's a bytes message) +1 3) MESSAGE\n...\ntransformer:default (server tells client to use content-length to make determination) -1 same as #3 above 4) MESSAGE\n...\n (no transformer specified - same as #3) +1 5) MESSAGE\n...\ntransformer:bob (server tells client to use unknown transformer - use default) -1 same as #5 above This does highlight that we have two real transform cases, send and receive if we support CONNECT or SUBSCRIBE level transformers. We can infer the correct direct on MESSAGE and SEND, but not the others. As this would make the interface have all of two methods, I am quite happy combining it. Alternately we can have different headers on SUBSCRIBE and CONNECT -Brian