package chat.server.im;
|
|
import java.nio.charset.Charset;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
import com.xiaoleilu.hutool.util.StrUtil;
|
|
import chat.message.Callback;
|
import chat.message.SendMessageCallback;
|
import chat.security.AES;
|
import chat.server.call.HttpEnvelopWriter;
|
import chat.server.call.ResultCode;
|
import chat.server.call.ResultItem;
|
import chat.server.call.ResultOutputType;
|
import chat.server.moquette.message.ModifiedMqttPubAckMessage;
|
import chat.server.moquette.message.MqttFixedHeader;
|
import chat.server.moquette.message.MqttMessage;
|
import chat.server.moquette.message.MqttMessageIdVariableHeader;
|
import chat.server.moquette.message.MqttMessageType;
|
import chat.server.moquette.message.MqttQoS;
|
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.Unpooled;
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
import io.netty.handler.codec.http.DefaultHttpHeaders;
|
import io.netty.handler.codec.http.FullHttpResponse;
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
import io.netty.handler.codec.http.HttpHeaderValues;
|
import io.netty.handler.codec.http.HttpHeaders;
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
import io.netty.handler.codec.http.HttpVersion;
|
|
public class ResultPool {
|
|
private static HttpEnvelopWriter httpEnvelopWriter;
|
|
private RequestType requestType;
|
private String topic;
|
private ResultCode code;
|
private String rootName;
|
private List<ResultItem> items;
|
private int messageId;
|
private String secret;
|
private ResultOutputType outputType;
|
private int resultCode;
|
private byte[] bytes;
|
private Object content = Unpooled.EMPTY_BUFFER;
|
private boolean needReturnCode;
|
|
static {
|
httpEnvelopWriter = HttpEnvelopWriter.getInstance();
|
}
|
|
public ResultPool(RequestType requestType, String topic, int messageId, String secret) {
|
this.rootName = "result";
|
this.items = new ArrayList<ResultItem>();
|
this.code = ResultCode.Success;
|
this.outputType = ResultOutputType.Bytes;
|
this.requestType = requestType;
|
this.resultCode = ResultCode.Success.getValue();
|
this.topic = topic;
|
this.messageId = messageId;
|
this.secret = secret;
|
this.needReturnCode = true;
|
}
|
|
public Object getResultData() {
|
//1. get data
|
ByteBuf payload = null;
|
|
if (ResultOutputType.JSON == outputType) {
|
payload = getJSONPayload();
|
}
|
else if (ResultOutputType.Bytes == outputType) {
|
payload = getBytesPayload();
|
}
|
|
if (payload == null) {
|
return null;
|
}
|
|
//2. get result
|
Object result = null;
|
|
if (RequestType.Short == requestType) {
|
result = getFullResponse(payload);
|
}
|
else if (RequestType.Long == requestType) {
|
result = getMqttMessage(payload);
|
}
|
|
return result;
|
}
|
|
public ByteBuf getJSONPayload() {
|
StringBuilder builder = httpEnvelopWriter.writeToString(this);
|
ByteBuf payload = Unpooled.copiedBuffer(builder.toString(), Charset.forName("utf-8"));
|
|
return payload;
|
}
|
|
public ByteBuf getBytesPayload() {
|
//1.
|
ByteBuf payload = Unpooled.buffer();
|
payload.ensureWritable(1).writeByte(resultCode);
|
|
//2.
|
if (bytes != null) {
|
byte[] data = AES.AESEncrypt(bytes, secret);
|
payload.ensureWritable(data.length).writeBytes(data);
|
}
|
|
//3. return
|
return payload;
|
}
|
|
public FullHttpResponse getFullResponse(ByteBuf payload) {
|
//1. new response
|
FullHttpResponse result = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, payload);
|
// FullHttpResponse result;
|
// if (ResultOutputType.JSON == outputType) {
|
// result = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, payload);
|
// }
|
// else {
|
// byte[] response = new byte[payload.readableBytes()];
|
// payload.readBytes(response);
|
//
|
// this.content = Unpooled.copiedBuffer(response);
|
//
|
// ByteBuf byteBuf = (ByteBuf) content;
|
//
|
// result = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);
|
// }
|
|
//2. header
|
HttpHeaders headers = new DefaultHttpHeaders();
|
|
headers.set(HttpHeaderNames.CONNECTION.toString(), HttpHeaderValues.KEEP_ALIVE.toString());
|
|
if (ResultOutputType.JSON == outputType) {
|
//headers.set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
|
headers.set(HttpHeaderNames.CONTENT_TYPE, "application/json;charset=utf-8");
|
headers.set(HttpHeaderNames.CONTENT_ENCODING.toString(), "utf-8");
|
//headers.set(HttpHeaderNames.CONTENT_TYPE.toString(), StrUtil.format("{};charset={}", "application/json", "UTF-8"));
|
}
|
else {
|
headers.set(HttpHeaderNames.CONTENT_TYPE.toString(), "application/octet-stream");
|
// headers.set(HttpHeaderNames.CONNECTION.toString(), HttpHeaderValues.KEEP_ALIVE.toString());
|
}
|
|
headers.set(HttpHeaderNames.CONTENT_LENGTH.toString(), payload.readableBytes());
|
result.headers().add(headers);
|
|
//3. return
|
return result;
|
}
|
|
public MqttMessage getMqttMessage(ByteBuf payload) {
|
if (payload == null) {
|
return null;
|
}
|
|
MqttMessageIdVariableHeader header = MqttMessageIdVariableHeader.from(messageId);
|
MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBACK, false, MqttQoS.AT_MOST_ONCE, false, 0);
|
ModifiedMqttPubAckMessage pubAckMessage = new ModifiedMqttPubAckMessage(fixedHeader, header, payload);
|
|
return pubAckMessage;
|
}
|
|
public void add(Object value) {
|
add(null, value);
|
}
|
|
public void add(String name, Object value) {
|
outputType = ResultOutputType.JSON;
|
add(name, value, true);
|
}
|
|
public void add(String name, Object value, boolean needEncode) {
|
ResultItem resultItem = null;
|
if (("key").equals(name)) {
|
outputType = ResultOutputType.JSON;
|
}
|
|
if (name != null) {
|
for (ResultItem item : items) {
|
if (name.equalsIgnoreCase(item.getName())) {
|
resultItem = item;
|
break;
|
}
|
}
|
}
|
|
if (resultItem == null) {
|
resultItem = new ResultItem();
|
resultItem.setName(name);
|
}
|
|
resultItem.setValue(value);
|
resultItem.setNeedEncode(needEncode);
|
|
items.add(resultItem);
|
}
|
|
public void error(ResultCode code) {
|
this.code = code;
|
}
|
|
public void success() {
|
this.code = ResultCode.Success;
|
}
|
|
public boolean isSuccess() {
|
return this.code == ResultCode.Success;
|
}
|
|
public List<ResultItem> getItemList() {
|
return items;
|
}
|
|
public String getErrorMessage() {
|
return code.getMsg();
|
}
|
|
public int getErrorCode() {
|
return code.getValue();
|
}
|
|
public ResultCode getCode() {
|
return code;
|
}
|
|
public ResultOutputType getOutputType() {
|
return outputType;
|
}
|
|
public void setOutputType(ResultOutputType outputType) {
|
this.outputType = outputType;
|
}
|
|
public String getRootName() {
|
return rootName;
|
}
|
|
public void setRootName(String rootName) {
|
this.rootName = rootName;
|
}
|
|
public void setBytes(byte[] bytes) {
|
outputType = ResultOutputType.Bytes;
|
|
if (bytes != null) {
|
ByteBuf ackPayload = Unpooled.buffer();
|
ackPayload.ensureWritable(bytes.length).writeBytes(bytes);
|
|
byte[] resBytes = new byte[ackPayload.readableBytes()];
|
ackPayload.getBytes(0, resBytes);
|
this.bytes = resBytes;
|
} else {
|
this.bytes = bytes;
|
}
|
}
|
|
public void setBytes(int resultCode, byte[] bytes) {
|
this.outputType = ResultOutputType.Bytes;
|
this.resultCode = resultCode;
|
this.bytes = bytes;
|
}
|
|
public RequestType getRequestType() {
|
return requestType;
|
}
|
|
public void setRequestType(RequestType requestType) {
|
this.requestType = requestType;
|
}
|
|
public String getTopic() {
|
return topic;
|
}
|
|
public Callback getCallback() {
|
// TODO Auto-generated method stub
|
return null;
|
}
|
|
public void setCallback(SendMessageCallback callback) {
|
// TODO Auto-generated method stub
|
|
}
|
|
public boolean isNeedReturnCode() {
|
return needReturnCode;
|
}
|
|
public void setNeedReturnCode(boolean needReturnCode) {
|
this.needReturnCode = needReturnCode;
|
}
|
|
}
|