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 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(); 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 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; } }