On a related note, I was playing with the TCP 'NetServer' yesterday, and noticed that the handler gets raw packets containing whatever the tcp stack has assembled at the time the event fires...
vertx run org.vertx.java.examples.echo.EchoClient -cp classes
vert.x-core-thread-0 Net client sending: hello0
vert.x-core-thread-0 Net client sending: hello1
vert.x-core-thread-0 Net client sending: hello2
vert.x-core-thread-0 Net client sending: hello3
vert.x-core-thread-0 Net client sending: hello4
vert.x-core-thread-0 Net client sending: hello5
vert.x-core-thread-0 Net client sending: hello6
vert.x-core-thread-0 Net client sending: hello7
vert.x-core-thread-0 Net client sending: hello8
vert.x-core-thread-0 Net client sending: hello9
vert.x-core-thread-0 Net client receiving: he
vert.x-core-thread-0 Net client receiving: llo0
hello1
vert.x-core-thread-0 Net client receiving: hello2
hello3
hello4
hello5
hello6
hello7
hello8
hello9
In Spring Integration we provide a number of pluggable serializers/deserializers (aka codecs) that apply structure to the TCP stream; message demarcation occurs at a pretty low level so the app only deals with reassembled "messages". For vert.x, do you feel this functionality belongs in the handler?
Just that if you are considering adding a parser for multi-part form data, maybe you could generalize it into a pluggable strategy for any stream?
The RecordParser can handle the case you describe (length prefixed), in
fact we use it for parsing the vert.x cluster messages which are passed
between nodes and are length prefixed.
As I mentioned previously the record parser can switch between delimited
and fixed length, and the size and the delimiter without creating a new
instance, this means you can parse complex protocols which have a
mixture of fixed length and delimited fields.
BTW length prefixed is not actually a new type in itself, it's just
fixed length.
E.g. if you have a protocol where the first 4 bytes is the length and
the next X bytes is the record, then you can think of that as two fixed
length records:
1) Of length 4, which holds a value representing the length L of the data
2) Of length L
So it's still can be parsed by a fixed length parser as long as you can
change the record length between reads (which you can with the vert.x one)
>
> Another common format is <stx>...<etx> or <soh>...<eot> or
> <soh>...<sot>...<etx>...<eot>
Parsing markup is a whole different kettle of fish. That's not within
scope of the vert.x record parser. For that I would recommend a specific
parser for the markup.
>
> Finally, I think having the parser itself be a 'Handler' is rather
> restrictive; if I want to plug in a different protocol, I have to
> craft a new java class.
...or Groovy class, or Ruby, or JS.
But you still have to describe the protocol format somewhere. If it's
not in a class or script where is it? In xml?
--
Tim Fox
Vert.x - effortless polyglot asynchronous application development
http://vertx.io
twitter:@timfox
This is not markup <stx> is ascii code 0x02, <etx> =0x03 etc etc. It's
simple Ascii data bracketed by control codes.
>>
>> Finally, I think having the parser itself be a 'Handler' is rather
>> restrictive; if I want to plug in a different protocol, I have to
>> craft a new java class.
> ...or Groovy class, or Ruby, or JS.
>
> But you still have to describe the protocol format somewhere. If it's
> not in a class or script where is it? In xml?
>
Yes, but let's say I want two versions of your PubSubServer, one with
delimited, one with fixed; I'd need two complete servers
public void start() {
vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
public void handle(final NetSocket socket) {
socket.dataHandler(RecordParser.newDelimited("\n", new
Handler<Buffer>() {
public void handle(Buffer frame) {
...
public void start() {
vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
public void handle(final NetSocket socket) {
socket.dataHandler(RecordParser.newFixed(42, new
Handler<Buffer>() {
public void handle(Buffer frame) {
...
I'd prefer to be able to plug in the protocol, with something like
private Parser parser; // actual implementation injected during
initialization
public void start() {
vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
public void handle(final NetSocket socket) {
socket.dataHandler(PubSubServer.this.parser.setHandler(new
Handler<Buffer>() {
public void handle(Buffer frame) {
...
public interface Parser extends Handler<Buffer> {
Handler<Buffer> setHandler(Handler<Buffer> handler);
}
public static class CustomParser implements Parser {
private Handler<Buffer> handler;
public Handler<Buffer> setHandler(Handler<Buffer> handler) {
this.handler = handler;
return this;
}
...
}
It would be nice if all handlers had a
Handler<E> setHandler(Handler<E> handler);
method.
That way, I could assemble the server's call stack from previously
instantiated (injected) objects rather than using hard-wired constructors.
Ok, so it's just delimited.
>
>>>
>>> Finally, I think having the parser itself be a 'Handler' is rather
>>> restrictive; if I want to plug in a different protocol, I have to
>>> craft a new java class.
>> ...or Groovy class, or Ruby, or JS.
>>
>> But you still have to describe the protocol format somewhere. If it's
>> not in a class or script where is it? In xml?
>>
>
> Yes, but let's say I want two versions of your PubSubServer, one with
> delimited, one with fixed; I'd need two complete servers
>
> public void start() {
> vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
> public void handle(final NetSocket socket) {
> socket.dataHandler(RecordParser.newDelimited("\n", new
> Handler<Buffer>() {
> public void handle(Buffer frame) {
> ...
>
> public void start() {
> vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
> public void handle(final NetSocket socket) {
> socket.dataHandler(RecordParser.newFixed(42, new
> Handler<Buffer>() {
> public void handle(Buffer frame) {
> ...
Why would you need two servers?
>
>
> I'd prefer to be able to plug in the protocol, with something like
>
> private Parser parser; // actual implementation injected during
> initialization
>
> public void start() {
> vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
> public void handle(final NetSocket socket) {
> socket.dataHandler(PubSubServer.this.parser.setHandler(new
> Handler<Buffer>() {
> public void handle(Buffer frame) {
> ...
>
>
> public interface Parser extends Handler<Buffer> {
>
> Handler<Buffer> setHandler(Handler<Buffer> handler);
> }
>
> public static class CustomParser implements Parser {
>
> private Handler<Buffer> handler;
>
> public Handler<Buffer> setHandler(Handler<Buffer> handler) {
> this.handler = handler;
> return this;
> }
>
> ...
>
> }
>
>
> It would be nice if all handlers had a
>
> Handler<E> setHandler(Handler<E> handler);
>
> method.
>
> That way, I could assemble the server's call stack from previously
> instantiated (injected) objects rather than using hard-wired
> constructors.
To be honest I'm not sure what you're getting at here. I guess my
parsing must be faulty ;)
...except the beginning delimeter (STX etc) is not part of the data. A
message that doesn't start with STX is invalid and should be rejected.
>
>>
>>>>
>>>> Finally, I think having the parser itself be a 'Handler' is rather
>>>> restrictive; if I want to plug in a different protocol, I have to
>>>> craft a new java class.
>>> ...or Groovy class, or Ruby, or JS.
>>>
>>> But you still have to describe the protocol format somewhere. If
>>> it's not in a class or script where is it? In xml?
>>>
>>
>> Yes, but let's say I want two versions of your PubSubServer, one with
>> delimited, one with fixed; I'd need two complete servers
>>
>> public void start() {
>> vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
>> public void handle(final NetSocket socket) {
>> socket.dataHandler(RecordParser.newDelimited("\n", new
>> Handler<Buffer>() {
>> public void handle(Buffer frame) {
>> ...
>>
>> public void start() {
>> vertx.createNetServer().connectHandler(new Handler<NetSocket>() {
>> public void handle(final NetSocket socket) {
>> socket.dataHandler(RecordParser.newFixed(42, new
>> Handler<Buffer>() {
>> public void handle(Buffer frame) {
>> ...
>
> Why would you need two servers?
How else would you configure one to use a delimited parser and another
instance *of the same server* to use a fixed-length parser. The fact you
are wiring the handlers together in code precludes swapping out a
handler for a different one, without writing more code. I prefer a more
loosely coupled approach.
It was a quick attempt to show how you could wire pre-instantiated
handlers together, rather the new... new... new...
It's Inversion of Control - instead of the server instantiating
particular implementations of handlers, the actual implementations are
provided to the server during initialization. Spring provides Inversion
of Control via Dependency Injection; another IoC technique is to use the
factory pattern, where the user delegates to a factory to get an
implementation of an interface, rather than instantiating it directly
itself.
Again; it's all about loose coupling.
That functionality didn't exist when we built the Http API.But in any case, there is already a feature request for it.Feel free to send a pull request :)
The current pull request https://github.com/vert-x/vert.x/pull/235 is on the right track but is not complete.1) I am not sure I like the idea of putting this functionality directly into the core API
2) The current pull request is Java-centric. To complete the functionality would need it usable via *all* of the languages that Vert.x supports
3) Needs documentation too
El lunes, 30 de julio de 2012 13:54:51 UTC+2, Tim Fox escribió:The current pull request https://github.com/vert-x/vert.x/pull/235 is on the right track but is not complete.1) I am not sure I like the idea of putting this functionality directly into the core API
We have no preferences about this, if we can help moving the code into a module just tell us :) .
2) The current pull request is Java-centric. To complete the functionality would need it usable via *all* of the languages that Vert.x supports
There are documentation explaining how to do the bindings of the other supported languages? In case the answer is not, where we can find examples to view the pattern?
I don't think it needs to go into a module, I just don't like the idea of complicating the current HTTP API.I would envision the post decoder as just a handler which gets set on the current HTTP server, and which implements Handler<HttpServerRequest>
I don't think it needs to go into a module, I just don't like the idea of complicating the current HTTP API.I would envision the post decoder as just a handler which gets set on the current HTTP server, and which implements Handler<HttpServerRequest>
Cheers.
Cheers.
var pump = new vertx.Pump(data, file.getWriteStream());
Another question that comes to my mind is if there is a way to stablish a size limit to the incoming post stream or to the GET route.
There isn't an obvious documented method to implement this security restrictions.
Thanks in advance! :) , I'm wondering to understand a little bit more of vert.x internals to start helping, for now i'll assume my
limitations and continue studying the code.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To view this discussion on the web, visit https://groups.google.com/d/msg/vertx/-/hB-Zdve23zcJ.
To post to this group, send an email to ve...@googlegroups.com.
To unsubscribe from this group, send email to vertx+un...@googlegroups.com.