Netty :Unpooled.copiedBuffer 以块的形式向客户端发送长字符串消息
Netty :Unpooled.copiedBuffer sending messages to client in chunks for long string messages
我将 Netty 用于 TCP 服务器和 TCP 客户端应用程序。我正在使用 Unpooled.copiedBuffer(myMsg.getByte() , CharsetUtil_UTF_16) 向客户端写消息。问题在于非常大的字符串消息。客户端以块而不是单个消息的形式接收消息。
这就是我之前发送消息的方式,它能够将消息作为单个消息发送(使用 wrappedBuffer 而不是 copiedBuffer )。但是我希望我的消息针对大于 128 的字符串字符进行编码,因此我想使用 CharsetUtil 在 UTF_16 中进行编码,但这会破坏消息
vm_packaged = 新字符串(b);
ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());
ctx.write(resp1);
ctx.flush();
下面是我的服务器代码
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = "";
CoffeeSendAndReceiveUtil csar = new CoffeeSendAndReceiveUtil();
body = csar.parseMessage(req);
logger.info(new Date());
String vm_message=null;
String vm_message_final=null;
MachineDispatcher vmd = new MachineDispatcher();
vm_message = vmd.getMachineString(body);
JSONObject product_done = null;
try{
order = new JSONObject(body);
p_resp = new JSONObject(vm_message);
if(order.has(PayTmConstantUtil.order_no)){
order_id = order.getString(PayTmConstantUtil.order_no);
}
if(order.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.QRCODE)){
if(order.getString(MachineConstant.QR_TYPE).equalsIgnoreCase(MachineConstant.paytm)){
if(!p_resp.has(PayTmConstantUtil.ERROR)){
loop = true;
}
if(p_resp.has(PayTmConstantUtil.signature)){
paytm_checksum = p_resp.getString(PayTmConstantUtil.signature);
}
p_resp.remove(PayTmConstantUtil.signature);
vm_message_final = p_resp.toString();
}
else if(order.getString(MachineConstant.QR_TYPE).equalsIgnoreCase(MachineConstant.phonepe)){
vm_message_final = vm_message;
merchantId = p_resp.getJSONObject(PhonePeConstant.data).getString(PhonePeConstant.merchantId);
phonepe = true;
}
}
else if(order.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.PRODUCTDONE)){
product_done = new JSONObject(vm_message);
if(product_done.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.PRODUCTDONE_R)){
create_product = true;
}
vm_message_final = vm_message;
}
else{
vm_message_final = vm_message;
}
}
catch(JSONException je){
logger.error(je.getClass()+ " -- "+je.getMessage());
}
if(vm_message_final!=null){
CoffeeSendAndReceiveUtil csr = new CoffeeSendAndReceiveUtil();
byte[] b = csr.packageMsg(vm_message_final);
vm_packaged = new String(b);
ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());
ctx.write(resp1);
ctx.flush();
}
}
catch(Exception ex ){
logger.info("Exception in Channel Read");
logger.error(ex.getClass()+" -- "+ex.getMessage());
}
finally {
//ctx.close();
}
}
这就是 TCP 的工作原理...这里没有 "message boundaries" 的概念。通常你会做的是在你的字节序列前面加上一些长度字段,然后使用这个长度字段在另一个远程对等端重新组装序列。
请参阅 LengthFieldBasedFrameDecoder
(对于接收方)和 LengthFieldPrepender
对于发送方。
我将 Netty 用于 TCP 服务器和 TCP 客户端应用程序。我正在使用 Unpooled.copiedBuffer(myMsg.getByte() , CharsetUtil_UTF_16) 向客户端写消息。问题在于非常大的字符串消息。客户端以块而不是单个消息的形式接收消息。
这就是我之前发送消息的方式,它能够将消息作为单个消息发送(使用 wrappedBuffer 而不是 copiedBuffer )。但是我希望我的消息针对大于 128 的字符串字符进行编码,因此我想使用 CharsetUtil 在 UTF_16 中进行编码,但这会破坏消息 vm_packaged = 新字符串(b); ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());
ctx.write(resp1); ctx.flush();
下面是我的服务器代码
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = "";
CoffeeSendAndReceiveUtil csar = new CoffeeSendAndReceiveUtil();
body = csar.parseMessage(req);
logger.info(new Date());
String vm_message=null;
String vm_message_final=null;
MachineDispatcher vmd = new MachineDispatcher();
vm_message = vmd.getMachineString(body);
JSONObject product_done = null;
try{
order = new JSONObject(body);
p_resp = new JSONObject(vm_message);
if(order.has(PayTmConstantUtil.order_no)){
order_id = order.getString(PayTmConstantUtil.order_no);
}
if(order.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.QRCODE)){
if(order.getString(MachineConstant.QR_TYPE).equalsIgnoreCase(MachineConstant.paytm)){
if(!p_resp.has(PayTmConstantUtil.ERROR)){
loop = true;
}
if(p_resp.has(PayTmConstantUtil.signature)){
paytm_checksum = p_resp.getString(PayTmConstantUtil.signature);
}
p_resp.remove(PayTmConstantUtil.signature);
vm_message_final = p_resp.toString();
}
else if(order.getString(MachineConstant.QR_TYPE).equalsIgnoreCase(MachineConstant.phonepe)){
vm_message_final = vm_message;
merchantId = p_resp.getJSONObject(PhonePeConstant.data).getString(PhonePeConstant.merchantId);
phonepe = true;
}
}
else if(order.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.PRODUCTDONE)){
product_done = new JSONObject(vm_message);
if(product_done.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.PRODUCTDONE_R)){
create_product = true;
}
vm_message_final = vm_message;
}
else{
vm_message_final = vm_message;
}
}
catch(JSONException je){
logger.error(je.getClass()+ " -- "+je.getMessage());
}
if(vm_message_final!=null){
CoffeeSendAndReceiveUtil csr = new CoffeeSendAndReceiveUtil();
byte[] b = csr.packageMsg(vm_message_final);
vm_packaged = new String(b);
ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());
ctx.write(resp1);
ctx.flush();
}
}
catch(Exception ex ){
logger.info("Exception in Channel Read");
logger.error(ex.getClass()+" -- "+ex.getMessage());
}
finally {
//ctx.close();
}
}
这就是 TCP 的工作原理...这里没有 "message boundaries" 的概念。通常你会做的是在你的字节序列前面加上一些长度字段,然后使用这个长度字段在另一个远程对等端重新组装序列。
请参阅 LengthFieldBasedFrameDecoder
(对于接收方)和 LengthFieldPrepender
对于发送方。