消息实体:
MsgLite.MsgLiteInner msg = MsgLite.MsgLiteInner.newBuilder()
.setProtoType(20)
.setProtoClientNo(1)
.build();
UserAuth.UserAuthInner userAuthInner = UserAuth.UserAuthInner.newBuilder()
.setAuthType(1)
.setAppId(appId)
.setUserName(userName)
.setPwd("")
.setTimestamp(timeStamp)
.setDevice(20)
.setSig(sign)
.setSdkVersion("5.4.2r")
.setImei("00:FF:76:0F:C4:7B")
.setMode(1)
.setNetwork(5)
.build();
MsgLite.MsgLiteInner msgLite = ImMessageBuilder.builder()
.setContainer(msg)
.setBody(userAuthInner)
.build();
创建消息代码如下
com.yuntongxun.client.ImMessageBuilder
@Slf4j
public class ImMessageBuilder {
private MsgLite.MsgLiteInner msgLiteInner;
private byte[] payload;
public static ImMessageBuilder builder() {
return new ImMessageBuilder();
}
public ImMessageBuilder setContainer(MsgLite.MsgLiteInner msgLite) {
this.msgLiteInner = msgLite;
return this;
}
public <T extends MessageLite> ImMessageBuilder setBody(T t) {
// 作为输出流接收数据
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
try {
// 包装
CodedOutputStream codedOut = CodedOutputStream.newInstance(byteArrayOut);
codedOut.writeUInt32NoTag(t.getSerializedSize());
t.writeTo(codedOut);
// 不管当前缓冲区是否已满,强迫操作系统把缓冲区的内容立刻发送出去
codedOut.flush();
// 把输出流的值赋值给payload
this.payload = byteArrayOut.toByteArray();
} catch (Exception e) {
log.warn("设置请求内容失败", e);
} finally {
try {
byteArrayOut.close();
} catch (Exception e) {
}
}
return this;
}
// 通过给msgLiteInner赋值返回一个MsgLite.MsgLiteInner 类型
public MsgLite.MsgLiteInner build() {
if(this.payload!=null){
return msgLiteInner.toBuilder().setProtoData(ByteString.copyFrom(this.payload)).build();
}
return msgLiteInner.toBuilder().build();
}
}
分析
msg 标识此次传输消息的protoType,setBody() 存入消息实体,ByteArrayOutputStream可以在内存中模拟一个OutputStream,实际上是把一个byte[]数组在内存中变成一个OutputStream,在写入完成之后强制发送出去。
关于writeUInt32NoTag() 用法详见
com.google.protobuf.CodedOutputStream.ArrayEncoder#writeUInt32NoTag以及博客protobuf序列化一个int型整数1