RxNetty icon indicating copy to clipboard operation
RxNetty copied to clipboard

ServerSentEventDecoder expects `data` field to be last

Open rhart opened this issue 8 years ago • 9 comments

I think there is an issue with ServerSentEventDecoder when the data field is not last. As I understand it the fields in the stream can be in any order. I would expect the following test to pass

    @Test(timeout = 60000)
    public void testOutOfOrderFields() throws Exception {
        ServerSentEvent expected = newServerSentEvent(null, "1111", "foo");

        doTest("data: foo\nid: 1111\n", expected);
    }

rhart avatar Sep 08 '16 13:09 rhart

@rhart I am following the spec here

According to the spec, lastEventId (specified by id field) is a buffer of the last received id and should be used for subsequent events (data in this case). In the test case you have specified, the id 1111 will be used for any subsequent data events and not a previous data event.

NiteshKant avatar Sep 08 '16 16:09 NiteshKant

Sorry for my confusion but then I don't see why this test would pass

    @Test(timeout = 60000)
    public void testOutOfOrderFields() throws Exception {
        ServerSentEvent expected = newServerSentEvent(null, "1111", "foo");

        doTest("id: 1111\ndata: foo\n", expected);
    }

the tests produce the following streams respectivley

data: foo
id: 1111

id: 1111
data: foo

which are the same thing aren't they? In both cases the last event id would be set to 1111 before dispatching the event, which is triggered by the empty line.

rhart avatar Sep 08 '16 16:09 rhart

before dispatching the event, which is triggered by the empty line.

AFAIU, event is dispatched after a carriage return/line feed and not by an empty line.

NiteshKant avatar Sep 08 '16 17:09 NiteshKant

In the spec it says

If the line is empty (a blank line) Dispatch the event, as defined below.

rhart avatar Sep 08 '16 17:09 rhart

I tried consuming my stream with a browser and

data: foo
id: 1

data: foo
id: 2

data: foo
id: 3

data: foo
id: 4

data: foo
id: 5

results in

MessageEvent {isTrusted: true, data: "foo", origin: "http://localhost:5050", lastEventId: "1", source: null…}
MessageEvent {isTrusted: true, data: "foo", origin: "http://localhost:5050", lastEventId: "2", source: null…}
MessageEvent {isTrusted: true, data: "foo", origin: "http://localhost:5050", lastEventId: "3", source: null…}
MessageEvent {isTrusted: true, data: "foo", origin: "http://localhost:5050", lastEventId: "4", source: null…}
MessageEvent {isTrusted: true, data: "foo", origin: "http://localhost:5050", lastEventId: "5", source: null…}

rhart avatar Sep 09 '16 16:09 rhart

@rhart let me think more about this.

NiteshKant avatar Sep 10 '16 02:09 NiteshKant

@rhart you are correct. Currently, the code is dispatching on a new line but it should dispatch when it encounters an empty line.

I do not have cycles for this now, if you want to pick it up, let me know.

NiteshKant avatar Sep 12 '16 17:09 NiteshKant

I know that feeling :)
Happy to pick it up but I can't commit to when at the moment. Let's see who get's there first :)

rhart avatar Sep 12 '16 17:09 rhart

@rhart 😄 Thanks!

NiteshKant avatar Sep 13 '16 19:09 NiteshKant