org.atmosphere.socketio.transport.SocketIOPacketImpl Maven / Gradle / Ivy
/*
* Copyright 2014 Sebastien Dionne
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.atmosphere.socketio.transport;
import org.atmosphere.socketio.SocketIOException;
import org.atmosphere.socketio.SocketIOPacket;
import java.util.ArrayList;
import java.util.List;
/**
* @author Sebastien Dionne : [email protected]
*/
public class SocketIOPacketImpl implements SocketIOPacket {
public static final char SOCKETIO_MSG_DELIMITER = '\ufffd';
public final static String POST_RESPONSE = "1";
private final PacketType packetType;
private final String id;
private final String endpoint;
private final String data;
private boolean padding = false;
public SocketIOPacketImpl(PacketType frameType) {
this(frameType, null, null, null, false);
}
public SocketIOPacketImpl(PacketType frameType, String data) {
this(frameType, null, null, data, false);
}
public SocketIOPacketImpl(PacketType frameType, String data, boolean padding) {
this(frameType, null, null, data, padding);
}
public SocketIOPacketImpl(PacketType frameType, String id, String endpoint, String data) {
this(frameType, id, endpoint, data, false);
}
public SocketIOPacketImpl(PacketType frameType, String id, String endpoint, String data, boolean padding) {
this.packetType = frameType;
this.id = id;
this.endpoint = endpoint;
this.data = data;
this.padding = padding;
}
public PacketType getFrameType() {
return packetType;
}
public String getData() {
return data;
}
public void setPadding(boolean padding) {
this.padding = padding;
}
public String toString() {
StringBuilder sb = new StringBuilder();
//[message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data])
sb.append(packetType.value).append(":");
if (id != null) {
sb.append(id);
}
sb.append(":");
if (endpoint != null) {
sb.append(endpoint);
}
if (data != null) {
sb.append(":");
sb.append(data);
}
String msg = sb.toString();
if (padding) {
sb = new StringBuilder();
sb.append(SOCKETIO_MSG_DELIMITER).append(msg.length()).append(SOCKETIO_MSG_DELIMITER).append(msg);
msg = sb.toString();
}
return msg;
}
public enum PacketType {
UNKNOWN(-1),
DISCONNECT(0),
CONNECT(1),
HEARTBEAT(2),
MESSAGE(3),
JSON(4),
EVENT(5),
ACK(6),
ERROR(7),
NOOP(8);
private int value;
PacketType(int value) {
this.value = value;
}
public int value() {
return value;
}
public static PacketType fromInt(int val) {
switch (val) {
case 0:
return DISCONNECT;
case 1:
return CONNECT;
case 2:
return HEARTBEAT;
case 3:
return MESSAGE;
case 4:
return JSON;
case 5:
return EVENT;
case 6:
return ACK;
case 7:
return ERROR;
case 8:
return NOOP;
default:
return UNKNOWN;
}
}
}
private static SocketIOPacketImpl parse2(String data) throws SocketIOException {
try {
String array[] = data.split(":");
if (array.length < 1) {
System.err.println("Message invalide=" + data);
return null;
}
String type = null;
String id = null;
String endpoint = null;
String message = null;
//[message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data])
// 0::/test
// 1::/test?my=param
// 2::
// 3:1::blabla
// 4:1::{"a":"b"}
// 5:::{"args":["user1","user2 ecrit coucou"],"name":"user message"}
// 6:::4+["A","B"] ou 6:::4
// '7::' [endpoint] ':' [reason] '+' [advice]
// 8 ..
if (array.length == 1) {
type = array[0];
} else if (array.length == 2) {
type = array[0];
id = array[1];
} else if (array.length == 3) {
type = array[0];
id = array[1];
endpoint = array[2];
} else {
type = array[0];
id = array[1];
endpoint = array[2];
// skip the first 3 ":"
int start = data.indexOf(":");
start = data.indexOf(":", ++start);
start = data.indexOf(":", ++start);
if (start > -1) {
message = data.substring(start + 1);
}
}
return new SocketIOPacketImpl(PacketType.fromInt(Integer.parseInt(type)), id, endpoint, message);
} catch (Exception e) {
throw new SocketIOException("Invalid message = " + data, e);
}
}
public static List parse(String data) throws SocketIOException {
List messages = new ArrayList();
if (data == null || data.length() == 0) {
return messages;
}
try {
// look for delimiter
if (data.charAt(0) == SocketIOPacketImpl.SOCKETIO_MSG_DELIMITER) {
int size = data.length();
int previousDelimiterIndex = 1;
int nextDelimiterIndex = -1;
// find next delimiter
for (int i = 1; i < size; i++) {
for (; i < size; i++) {
if (data.charAt(i) == SocketIOPacketImpl.SOCKETIO_MSG_DELIMITER) {
nextDelimiterIndex = i;
break;
}
}
if (nextDelimiterIndex > previousDelimiterIndex) {
int length = Integer.parseInt(data.substring(previousDelimiterIndex, nextDelimiterIndex));
i = ++nextDelimiterIndex + length;
previousDelimiterIndex = i + 1;
SocketIOPacketImpl msg = parse2(data.substring(nextDelimiterIndex, i));
if (msg != null) {
messages.add(msg);
}
}
}
} else {
SocketIOPacketImpl msg = parse2(data);
if (msg != null) {
messages.add(msg);
}
}
return messages;
} catch (Exception e) {
throw new SocketIOException("Invalid message=" + data, e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy