From 0db1e9c2b08a19e8dd0583dbdbb6d20c00a14210 Mon Sep 17 00:00:00 2001 From: jfarcand Date: Thu, 24 May 2012 14:35:45 -0400 Subject: [PATCH] More fix for #286 Handling of "glued" messages. Make the token configurable on server and client, use messageDelimiter as well for finding the end of the message --- .../client/MessageLengthInterceptor.java | 23 +++++++++++++------ .../org/atmosphere/cpr/ApplicationConfig.java | 6 +++++ .../main/webapp/jquery/jquery.atmosphere.js | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/modules/cpr/src/main/java/org/atmosphere/client/MessageLengthInterceptor.java b/modules/cpr/src/main/java/org/atmosphere/client/MessageLengthInterceptor.java index f78aebf50b..5ce55898f7 100644 --- a/modules/cpr/src/main/java/org/atmosphere/client/MessageLengthInterceptor.java +++ b/modules/cpr/src/main/java/org/atmosphere/client/MessageLengthInterceptor.java @@ -16,6 +16,7 @@ package org.atmosphere.client; import org.atmosphere.cpr.Action; +import org.atmosphere.cpr.ApplicationConfig; import org.atmosphere.cpr.AsyncIOWriter; import org.atmosphere.cpr.AsyncIOWriterAdapter; import org.atmosphere.cpr.AtmosphereConfig; @@ -31,14 +32,22 @@ * An {@link AtmosphereInterceptor} that add a special String "<||>" at the end of a message, allowing the * atmosphere.js to detect if one or several messages where aggregated in one write operations. * + * The special String is configurable using {@link ApplicationConfig#MESSAGE_DELIMITER} + * * @author Jeanfrancois Arcand */ public class MessageLengthInterceptor implements AtmosphereInterceptor { - private final static byte[] END = "<||>".getBytes(); + private final static byte[] END = "|".getBytes(); + + private byte[] end = END; @Override public void configure(AtmosphereConfig config) { + String s = config.getInitParameter(ApplicationConfig.MESSAGE_DELIMITER); + if (s != null) { + end = s.getBytes(); + } } @Override @@ -68,13 +77,13 @@ public AsyncIOWriter write(String data) throws IOException { @Override public AsyncIOWriter write(byte[] data) throws IOException { - response.write(data).write(END); + response.write(data).write(end); return this; } @Override public AsyncIOWriter write(byte[] data, int offset, int length) throws IOException { - response.write(data, offset, length).write(END); + response.write(data, offset, length).write(end); return this; } @@ -100,18 +109,18 @@ public String filter(AtmosphereResponse r, String message) { @Override public byte[] filter(AtmosphereResponse r, byte[] message) { - byte[] nb = new byte[message.length + END.length]; + byte[] nb = new byte[message.length + end.length]; System.arraycopy(message, 0, nb, 0, message.length); - System.arraycopy(END, 0, nb, message.length, nb.length); + System.arraycopy(end, 0, nb, message.length, nb.length); return nb; } @Override public byte[] filter(AtmosphereResponse r, byte[] message, int offset, int length) { - byte[] nb = new byte[length+ END.length]; + byte[] nb = new byte[length+ end.length]; System.arraycopy(message, offset, nb, 0, length); - System.arraycopy(END, 0, nb, length, nb.length); + System.arraycopy(end, 0, nb, length, nb.length); return nb; } diff --git a/modules/cpr/src/main/java/org/atmosphere/cpr/ApplicationConfig.java b/modules/cpr/src/main/java/org/atmosphere/cpr/ApplicationConfig.java index 15a81d4989..45c554a690 100644 --- a/modules/cpr/src/main/java/org/atmosphere/cpr/ApplicationConfig.java +++ b/modules/cpr/src/main/java/org/atmosphere/cpr/ApplicationConfig.java @@ -15,6 +15,7 @@ */ package org.atmosphere.cpr; +import org.atmosphere.client.MessageLengthInterceptor; import org.atmosphere.websocket.WebSocketProtocol; /** @@ -261,4 +262,9 @@ public interface ApplicationConfig { * Regex pattern for excluding file from being serviced by {@link AtmosphereFilter} */ String ATMOSPHERE_EXCLUDED_FILE = AtmosphereFilter.class.getName() + ".excludes"; + /** + * The token used to separate broadcasted messages. This value is used by the client to parse several messages + * received in one chunk. Default is '<||>' + */ + String MESSAGE_DELIMITER = MessageLengthInterceptor.class.getName() + ".delimiter"; } diff --git a/modules/jquery/src/main/webapp/jquery/jquery.atmosphere.js b/modules/jquery/src/main/webapp/jquery/jquery.atmosphere.js index 3369c0f055..b14ed571fd 100644 --- a/modules/jquery/src/main/webapp/jquery/jquery.atmosphere.js +++ b/modules/jquery/src/main/webapp/jquery/jquery.atmosphere.js @@ -1611,7 +1611,7 @@ jQuery.atmosphere = function() { func(_response); }; - var messages = _response.responseBody.split("<||>"); + var messages = typeof(_response.responseBody) == 'string' ? _response.responseBody.split(_request.messageDelimiter) : new Array(_response.responseBody); for (i = 0; i < messages.length; i++) { if (messages.length > 1 && messages[i].length == 0) {