SncpClient优化
This commit is contained in:
@@ -7,10 +7,6 @@ redkale.lib = ./
|
|||||||
redkale.executor.threads = 4
|
redkale.executor.threads = 4
|
||||||
redkale.executor.hash = false
|
redkale.executor.hash = false
|
||||||
|
|
||||||
#\u3010transport\u8282\u70b9\u5168\u5c40\u552f\u4e00\u3011
|
|
||||||
redkale.transport.bufferCapacity = 32k
|
|
||||||
redkale.transport.bufferPoolSize = 32
|
|
||||||
|
|
||||||
#\u3010excludelibs\u8282\u70b9\u5168\u5c40\u552f\u4e00\u3011
|
#\u3010excludelibs\u8282\u70b9\u5168\u5c40\u552f\u4e00\u3011
|
||||||
redkale.excludelibs.value = ^.*mysql.*$;^.*kafka.*$
|
redkale.excludelibs.value = ^.*mysql.*$;^.*kafka.*$
|
||||||
|
|
||||||
|
|||||||
@@ -42,18 +42,6 @@
|
|||||||
-->
|
-->
|
||||||
<executor threads="4" hash="false"/>
|
<executor threads="4" hash="false"/>
|
||||||
|
|
||||||
<!--
|
|
||||||
【节点全局唯一】
|
|
||||||
transport节点只能有一个,用于配置所有Transport的池参数,没配置该节点将自动创建一个。
|
|
||||||
threads: 线程总数, 默认: <group>节点数*CPU核数*2
|
|
||||||
bufferCapacity: ByteBuffer的初始化大小, 默认: 32K;
|
|
||||||
bufferPoolSize: ByteBuffer池的大小,默认: 线程总数*4
|
|
||||||
readTimeoutSeconds: TCP读取超时秒数, 默认为6秒, 为0表示无超时限制
|
|
||||||
writeTimeoutSeconds: TCP写入超时秒数, 默认为6秒, 为0表示无超时限制
|
|
||||||
strategy: 远程请求的负载均衡策略, 必须是org.redkale.net.TransportStrategy的实现类
|
|
||||||
-->
|
|
||||||
<transport bufferCapacity="32K" bufferPoolSize="32" threads="32" readTimeoutSeconds="6" writeTimeoutSeconds="6"/>
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
【节点全局唯一】
|
【节点全局唯一】
|
||||||
自动扫描时排除部分包路径
|
自动扫描时排除部分包路径
|
||||||
@@ -127,9 +115,6 @@
|
|||||||
load: 加载文件,多个用;隔开。
|
load: 加载文件,多个用;隔开。
|
||||||
其他属性: 供org.redkale.boot.PropertiesAgentProvider使用判断
|
其他属性: 供org.redkale.boot.PropertiesAgentProvider使用判断
|
||||||
默认置入的system.property.的有:
|
默认置入的system.property.的有:
|
||||||
System.setProperty("redkale.net.transport.poolmaxconns", "100");
|
|
||||||
System.setProperty("redkale.net.transport.pinginterval", "30");
|
|
||||||
System.setProperty("redkale.net.transport.checkinterval", "30");
|
|
||||||
System.setProperty("redkale.convert.pool.size", "128");
|
System.setProperty("redkale.convert.pool.size", "128");
|
||||||
System.setProperty("redkale.convert.writer.buffer.defsize", "4096");
|
System.setProperty("redkale.convert.writer.buffer.defsize", "4096");
|
||||||
System.setProperty("redkale.trace.enable", "false");
|
System.setProperty("redkale.trace.enable", "false");
|
||||||
|
|||||||
@@ -303,15 +303,6 @@ public final class Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//设置默认系统变量
|
//设置默认系统变量
|
||||||
if (System.getProperty("redkale.net.transport.poolmaxconns") == null) {
|
|
||||||
System.setProperty("redkale.net.transport.poolmaxconns", "100");
|
|
||||||
}
|
|
||||||
if (System.getProperty("redkale.net.transport.pinginterval") == null) {
|
|
||||||
System.setProperty("redkale.net.transport.pinginterval", "30");
|
|
||||||
}
|
|
||||||
if (System.getProperty("redkale.net.transport.checkinterval") == null) {
|
|
||||||
System.setProperty("redkale.net.transport.checkinterval", "30");
|
|
||||||
}
|
|
||||||
if (System.getProperty("redkale.convert.pool.size") == null) {
|
if (System.getProperty("redkale.convert.pool.size") == null) {
|
||||||
System.setProperty("redkale.convert.pool.size", "128");
|
System.setProperty("redkale.convert.pool.size", "128");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -928,9 +928,6 @@ public abstract class NodeServer {
|
|||||||
if ("executor".equals(key)) {
|
if ("executor".equals(key)) {
|
||||||
return AnyValue.MergeFunction.REPLACE;
|
return AnyValue.MergeFunction.REPLACE;
|
||||||
}
|
}
|
||||||
if ("transport".equals(key)) {
|
|
||||||
return AnyValue.MergeFunction.REPLACE;
|
|
||||||
}
|
|
||||||
if ("excludelibs".equals(key)) {
|
if ("excludelibs".equals(key)) {
|
||||||
return AnyValue.MergeFunction.REPLACE;
|
return AnyValue.MergeFunction.REPLACE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,15 +74,6 @@ public class BsonWriter extends Writer implements ByteTuple {
|
|||||||
return new ByteArray(this);
|
return new ByteArray(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toArray() {
|
|
||||||
if (count == content.length) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
byte[] newdata = new byte[count];
|
|
||||||
System.arraycopy(content, 0, newdata, 0, count);
|
|
||||||
return newdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ByteBuffer[] toBuffers() {
|
public ByteBuffer[] toBuffers() {
|
||||||
return new ByteBuffer[]{ByteBuffer.wrap(content, 0, count)};
|
return new ByteBuffer[]{ByteBuffer.wrap(content, 0, count)};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,7 +276,8 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
private void completeInIOThread(boolean kill) {
|
private void completeInIOThread(boolean kill) {
|
||||||
if (!this.inited) {
|
if (!this.inited) {
|
||||||
return; //避免重复关闭
|
return; //避免重复关闭
|
||||||
} //System.println("耗时: " + (System.currentTimeMillis() - request.createtime));
|
}
|
||||||
|
//System.println("耗时: " + (System.currentTimeMillis() - request.createtime));
|
||||||
if (kill) {
|
if (kill) {
|
||||||
refuseAlive();
|
refuseAlive();
|
||||||
}
|
}
|
||||||
@@ -300,7 +301,6 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
new ProtocolCodec(context, poolSupplier, poolConsumer, conn).response(this).run(null);
|
new ProtocolCodec(context, poolSupplier, poolConsumer, conn).response(this).run(null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new Exception().printStackTrace();
|
|
||||||
this.responseConsumer.accept(this);
|
this.responseConsumer.accept(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.redkale.convert.json.JsonConvert;
|
|||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 传输客户端
|
* 被net.client模块代替
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ import org.redkale.service.Service;
|
|||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System.getProperty("redkale.net.transport.ping.interval", "30") 心跳周期,默认30秒
|
* 被net.client模块代替
|
||||||
* System.getProperty("redkale.net.transport.check.interval", "30") 检查不可用地址周期,默认30秒
|
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import org.redkale.convert.json.JsonConvert;
|
|||||||
import org.redkale.util.Utility;
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 协议地址组合对象, 对应application.xml 中 resources->group 节点信息
|
* 被net.client模块代替
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.net.SocketAddress;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程请求的负载均衡策略
|
* 被net.client模块代替
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public abstract class ClientCodec<R extends ClientRequest, P> implements Complet
|
|||||||
for (ClientResponse<R, P> cr : respResults) {
|
for (ClientResponse<R, P> cr : respResults) {
|
||||||
connection.doneResponseCounter.increment();
|
connection.doneResponseCounter.increment();
|
||||||
if (cr.isError()) {
|
if (cr.isError()) {
|
||||||
connection.dispose(null);
|
connection.dispose(cr.exc);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
ClientFuture<R, P> respFuture = connection.pollRespFuture(cr.getRequestid());
|
ClientFuture<R, P> respFuture = connection.pollRespFuture(cr.getRequestid());
|
||||||
|
|||||||
@@ -3,16 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.net.sncp;
|
package org.redkale.net.sncp;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.channels.CompletionHandler;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.redkale.convert.*;
|
|
||||||
import org.redkale.convert.bson.BsonConvert;
|
|
||||||
import org.redkale.net.*;
|
import org.redkale.net.*;
|
||||||
import org.redkale.net.client.*;
|
import org.redkale.net.client.*;
|
||||||
import org.redkale.net.sncp.SncpRemoteInfo.SncpRemoteAction;
|
|
||||||
import org.redkale.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SNCP版Client, 一个SncpServer只能对应一个SncpClient
|
* SNCP版Client, 一个SncpServer只能对应一个SncpClient
|
||||||
@@ -26,7 +20,7 @@ import org.redkale.util.*;
|
|||||||
*/
|
*/
|
||||||
public class SncpClient extends Client<SncpClientConnection, SncpClientRequest, SncpClientResult> {
|
public class SncpClient extends Client<SncpClientConnection, SncpClientRequest, SncpClientResult> {
|
||||||
|
|
||||||
private final InetSocketAddress clientSncpAddress;
|
final InetSocketAddress clientSncpAddress;
|
||||||
|
|
||||||
public SncpClient(String name, AsyncGroup group, InetSocketAddress clientSncpAddress, ClientAddress address, String netprotocol, int maxConns, int maxPipelines) {
|
public SncpClient(String name, AsyncGroup group, InetSocketAddress clientSncpAddress, ClientAddress address, String netprotocol, int maxConns, int maxPipelines) {
|
||||||
super(name, group, "TCP".equalsIgnoreCase(netprotocol), address, maxConns, maxPipelines, null, null, null); //maxConns
|
super(name, group, "TCP".equalsIgnoreCase(netprotocol), address, maxConns, maxPipelines, null, null, null); //maxConns
|
||||||
@@ -47,91 +41,9 @@ public class SncpClient extends Client<SncpClientConnection, SncpClientRequest,
|
|||||||
return super.connect(addr);
|
return super.connect(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//只给远程模式调用的
|
@Override
|
||||||
public <T> T remote(final SncpRemoteInfo info, final int index, final Object[] params) {
|
protected CompletableFuture<SncpClientResult> writeChannel(ClientConnection conn, SncpClientRequest request) {
|
||||||
final Convert convert = info.convert;
|
return super.writeChannel(conn, request);
|
||||||
final SncpRemoteAction action = info.actions[index];
|
|
||||||
CompletionHandler callbackHandler = null;
|
|
||||||
Object callbackHandlerAttach = null;
|
|
||||||
if (action.paramHandlerIndex >= 0) {
|
|
||||||
callbackHandler = (CompletionHandler) params[action.paramHandlerIndex];
|
|
||||||
params[action.paramHandlerIndex] = null;
|
|
||||||
if (action.paramHandlerAttachIndex >= 0) {
|
|
||||||
callbackHandlerAttach = params[action.paramHandlerAttachIndex];
|
|
||||||
params[action.paramHandlerAttachIndex] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final CompletableFuture<byte[]> future = remote(info, action, convert, Traces.currTraceid(), params);
|
|
||||||
if (action.paramHandlerIndex >= 0) { //参数中存在CompletionHandler
|
|
||||||
final CompletionHandler handler = callbackHandler;
|
|
||||||
final Object attach = callbackHandlerAttach;
|
|
||||||
if (handler == null) { //传入的CompletionHandler参数为null
|
|
||||||
future.join();
|
|
||||||
} else {
|
|
||||||
future.whenComplete((v, t) -> {
|
|
||||||
if (t == null) {
|
|
||||||
//v,length-1为了读掉(byte)0
|
|
||||||
handler.completed(v == null ? null : convert.convertFrom(action.paramHandlerResultType, v, 1, v.length - 1), attach);
|
|
||||||
} else {
|
|
||||||
handler.failed(t, attach);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (action.returnFutureClass != null) { //返回类型为CompletableFuture
|
|
||||||
if (action.returnFutureClass == CompletableFuture.class) {
|
|
||||||
//v,length-1为了读掉(byte)0
|
|
||||||
return (T) future.thenApply(v -> v == null ? null : convert.convertFrom(action.returnFutureResultType, v, 1, v.length - 1));
|
|
||||||
} else {
|
|
||||||
final CompletableFuture returnFuture = action.returnFutureCreator.create();
|
|
||||||
future.whenComplete((v, t) -> {
|
|
||||||
if (t == null) {
|
|
||||||
//v,length-1为了读掉(byte)0
|
|
||||||
returnFuture.complete(v == null ? null : convert.convertFrom(action.returnFutureResultType, v, 1, v.length - 1));
|
|
||||||
} else {
|
|
||||||
returnFuture.completeExceptionally(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return (T) returnFuture;
|
|
||||||
}
|
|
||||||
} else if (action.returnObjectType != null) { //返回类型为JavaBean
|
|
||||||
//v,length-1为了读掉(byte)0
|
|
||||||
return (T) future.thenApply(v -> v == null ? null : convert.convertFrom(action.returnObjectType, v, 1, v.length - 1)).join();
|
|
||||||
} else { //返回类型为void
|
|
||||||
future.join();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<byte[]> remote(
|
|
||||||
final SncpRemoteInfo info,
|
|
||||||
final SncpRemoteAction action,
|
|
||||||
final Convert convert,
|
|
||||||
final String traceid,
|
|
||||||
final Object[] params) {
|
|
||||||
final Type[] myParamTypes = action.paramTypes;
|
|
||||||
final Class[] myParamClass = action.paramClasses;
|
|
||||||
if (action.paramAddressSourceIndex >= 0) {
|
|
||||||
params[action.paramAddressSourceIndex] = this.clientSncpAddress;
|
|
||||||
}
|
|
||||||
final long seqid = System.nanoTime();
|
|
||||||
final SncpClientRequest requet = new SncpClientRequest();
|
|
||||||
Writer writer = null;
|
|
||||||
if (myParamTypes.length > 0) {
|
|
||||||
writer = convert.pollWriter();
|
|
||||||
for (int i = 0; i < params.length; i++) { //service方法的参数
|
|
||||||
Convert bcc = convert;
|
|
||||||
if (params[i] instanceof org.redkale.service.RetResult) {
|
|
||||||
org.redkale.convert.Convert cc = ((org.redkale.service.RetResult) params[i]).convert();
|
|
||||||
if (cc instanceof BsonConvert) {
|
|
||||||
bcc = (BsonConvert) cc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bcc.convertTo(writer, CompletionHandler.class.isAssignableFrom(myParamClass[i]) ? CompletionHandler.class : myParamTypes[i], params[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requet.prepare(action.header, seqid, traceid, (ByteTuple) writer);
|
|
||||||
//writer没有回收,待优化
|
|
||||||
final SocketAddress addr = action.paramAddressTargetIndex >= 0 ? (SocketAddress) params[action.paramAddressTargetIndex] : info.nextRemoteAddress();
|
|
||||||
return super.connect(addr).thenCompose(conn -> writeChannel(conn, requet).thenApply(rs -> rs.getBodyContent()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ public class SncpClientCodec extends ClientCodec<SncpClientRequest, SncpClientRe
|
|||||||
occurError(null, new SncpException("sncp header length must be " + HEADER_SIZE + ", but " + headerSize)); //request不一定存在
|
occurError(null, new SncpException("sncp header length must be " + HEADER_SIZE + ", but " + headerSize)); //request不一定存在
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//if (halfHeaderBytes.length() != HEADER_SIZE) {
|
||||||
|
// logger.log(Level.SEVERE, "halfHeaderBytes.length must be " + HEADER_SIZE + ", but " + halfHeaderBytes.length());
|
||||||
|
//}
|
||||||
halfHeaderBytes = null;
|
halfHeaderBytes = null;
|
||||||
if (result.getBodyLength() < 1) {
|
if (result.getBodyLength() < 1) {
|
||||||
addMessage(findRequest(result.getRequestid()), result);
|
addMessage(findRequest(result.getRequestid()), result);
|
||||||
@@ -90,6 +93,9 @@ public class SncpClientCodec extends ClientCodec<SncpClientRequest, SncpClientRe
|
|||||||
halfBodyBytes.put(buffer, lastResult.getBodyLength() - halfBodyBytes.length());
|
halfBodyBytes.put(buffer, lastResult.getBodyLength() - halfBodyBytes.length());
|
||||||
//读取完整body
|
//读取完整body
|
||||||
lastResult.setBodyContent(halfBodyBytes.getBytes());
|
lastResult.setBodyContent(halfBodyBytes.getBytes());
|
||||||
|
//if (halfBodyBytes.length() != lastResult.getBodyLength()) {
|
||||||
|
// logger.log(Level.SEVERE, "halfBodyBytes.length must be " + lastResult.getBodyLength() + ", but " + halfBodyBytes.length());
|
||||||
|
//}
|
||||||
halfBodyBytes = null;
|
halfBodyBytes = null;
|
||||||
addMessage(findRequest(lastResult.getRequestid()), lastResult);
|
addMessage(findRequest(lastResult.getRequestid()), lastResult);
|
||||||
lastResult = null;
|
lastResult = null;
|
||||||
@@ -100,8 +106,12 @@ public class SncpClientCodec extends ClientCodec<SncpClientRequest, SncpClientRe
|
|||||||
halfBodyBytes.put(buffer);
|
halfBodyBytes.put(buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//有足够的数据读取完整body
|
||||||
lastResult.readBody(buffer);
|
lastResult.readBody(buffer);
|
||||||
halfBodyBytes = null;
|
halfBodyBytes = null;
|
||||||
|
//if (lastResult.getBodyContent().length != lastResult.getBodyLength()) {
|
||||||
|
// logger.log(Level.SEVERE, "lastResult.length must be " + lastResult.getBodyLength() + ", but " + lastResult.getBodyContent().length);
|
||||||
|
//}
|
||||||
addMessage(findRequest(lastResult.getRequestid()), lastResult);
|
addMessage(findRequest(lastResult.getRequestid()), lastResult);
|
||||||
lastResult = null;
|
lastResult = null;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ package org.redkale.net.sncp;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.redkale.net.client.*;
|
import org.redkale.net.client.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.ByteArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* client版请求
|
* client版请求
|
||||||
@@ -24,12 +24,12 @@ public class SncpClientRequest extends ClientRequest {
|
|||||||
|
|
||||||
private long seqid;
|
private long seqid;
|
||||||
|
|
||||||
private ByteTuple bodyContent;
|
private byte[] bodyContent;
|
||||||
|
|
||||||
public SncpClientRequest() {
|
public SncpClientRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SncpClientRequest prepare(SncpHeader header, long seqid, String traceid, ByteTuple bodyContent) {
|
public SncpClientRequest prepare(SncpHeader header, long seqid, String traceid, byte[] bodyContent) {
|
||||||
super.prepare();
|
super.prepare();
|
||||||
this.header = header;
|
this.header = header;
|
||||||
this.seqid = seqid;
|
this.seqid = seqid;
|
||||||
@@ -59,10 +59,10 @@ public class SncpClientRequest extends ClientRequest {
|
|||||||
@Override
|
@Override
|
||||||
public void writeTo(ClientConnection conn, ByteArray array) {
|
public void writeTo(ClientConnection conn, ByteArray array) {
|
||||||
array.putPlaceholder(SncpHeader.HEADER_SIZE);
|
array.putPlaceholder(SncpHeader.HEADER_SIZE);
|
||||||
if (bodyContent == null || bodyContent.length() == 0) {
|
if (bodyContent == null) {
|
||||||
header.writeTo(array, header.getAddrBytes(), header.getAddrPort(), seqid, 0, 0);
|
header.writeTo(array, header.getAddrBytes(), header.getAddrPort(), seqid, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
header.writeTo(array, header.getAddrBytes(), header.getAddrPort(), seqid, bodyContent.length(), 0);
|
header.writeTo(array, header.getAddrBytes(), header.getAddrPort(), seqid, bodyContent.length, 0);
|
||||||
array.put(bodyContent);
|
array.put(bodyContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ public class SncpClientRequest extends ClientRequest {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "_" + Objects.hashCode(this) + "{"
|
return getClass().getSimpleName() + "_" + Objects.hashCode(this) + "{"
|
||||||
+ "header=" + header + ", seqid =" + seqid
|
+ "header=" + header + ", seqid =" + seqid
|
||||||
+ ", body=[" + (bodyContent == null ? -1 : bodyContent.length()) + "]"
|
+ ", body=[" + (bodyContent == null ? -1 : bodyContent.length) + "]"
|
||||||
+ "}";
|
+ "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ public class SncpClientRequest extends ClientRequest {
|
|||||||
return seqid;
|
return seqid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteTuple getBodyContent() {
|
public byte[] getBodyContent() {
|
||||||
return bodyContent;
|
return bodyContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,12 @@ public class SncpHeader {
|
|||||||
this.addrPort = clientSncpAddress == null ? 0 : clientSncpAddress.getPort();
|
this.addrPort = clientSncpAddress == null ? 0 : clientSncpAddress.getPort();
|
||||||
this.serviceid = serviceid;
|
this.serviceid = serviceid;
|
||||||
this.actionid = actionid;
|
this.actionid = actionid;
|
||||||
|
if (addrBytes.length != 4) {
|
||||||
|
throw new SncpException("address bytes length must be 4, but " + addrBytes.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//返回Header Size
|
||||||
public int read(ByteBuffer buffer) {
|
public int read(ByteBuffer buffer) {
|
||||||
this.seqid = buffer.getLong(); //8
|
this.seqid = buffer.getLong(); //8
|
||||||
int size = buffer.getChar();
|
int size = buffer.getChar();
|
||||||
@@ -76,6 +80,7 @@ public class SncpHeader {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//返回Header Size
|
||||||
public int read(ByteArray array) {
|
public int read(ByteArray array) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
this.seqid = array.getLong(offset); //8
|
this.seqid = array.getLong(offset); //8
|
||||||
@@ -96,7 +101,7 @@ public class SncpHeader {
|
|||||||
this.abilities = array.getInt(offset); //4
|
this.abilities = array.getInt(offset); //4
|
||||||
offset += 4;
|
offset += 4;
|
||||||
this.timestamp = array.getLong(offset); //8
|
this.timestamp = array.getLong(offset); //8
|
||||||
offset += 4;
|
offset += 8;
|
||||||
this.retcode = array.getInt(offset); //4
|
this.retcode = array.getInt(offset); //4
|
||||||
offset += 4;
|
offset += 4;
|
||||||
this.bodyLength = array.getInt(offset); //4
|
this.bodyLength = array.getInt(offset); //4
|
||||||
@@ -110,6 +115,9 @@ public class SncpHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ByteArray writeTo(ByteArray array, byte[] newAddrBytes, int newAddrPort, long newSeqid, int bodyLength, int retcode) {
|
public ByteArray writeTo(ByteArray array, byte[] newAddrBytes, int newAddrPort, long newSeqid, int bodyLength, int retcode) {
|
||||||
|
if (newAddrBytes.length != 4) {
|
||||||
|
throw new SncpException("address bytes length must be 4, but " + newAddrBytes.length);
|
||||||
|
}
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
array.putLong(offset, newSeqid); //8
|
array.putLong(offset, newSeqid); //8
|
||||||
offset += 8;
|
offset += 8;
|
||||||
@@ -149,7 +157,7 @@ public class SncpHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InetSocketAddress getAddress() {
|
public InetSocketAddress getAddress() {
|
||||||
if (addrBytes == null || addrBytes[0] == 0) {
|
if (addrBytes == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new InetSocketAddress((0xff & addrBytes[0]) + "." + (0xff & addrBytes[1]) + "." + (0xff & addrBytes[2]) + "." + (0xff & addrBytes[3]), addrPort);
|
return new InetSocketAddress((0xff & addrBytes[0]) + "." + (0xff & addrBytes[1]) + "." + (0xff & addrBytes[2]) + "." + (0xff & addrBytes[3]), addrPort);
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ package org.redkale.net.sncp;
|
|||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.CompletionHandler;
|
import java.nio.channels.CompletionHandler;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import org.redkale.convert.Convert;
|
import java.util.logging.*;
|
||||||
|
import org.redkale.convert.*;
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
import org.redkale.mq.*;
|
import org.redkale.mq.*;
|
||||||
import static org.redkale.net.sncp.Sncp.loadMethodActions;
|
import static org.redkale.net.sncp.Sncp.loadMethodActions;
|
||||||
|
import static org.redkale.net.sncp.SncpHeader.HEADER_SIZE;
|
||||||
import org.redkale.service.*;
|
import org.redkale.service.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
@@ -26,7 +30,9 @@ import org.redkale.util.*;
|
|||||||
*
|
*
|
||||||
* @since 2.8.0
|
* @since 2.8.0
|
||||||
*/
|
*/
|
||||||
public final class SncpRemoteInfo<T extends Service> {
|
public class SncpRemoteInfo<T extends Service> {
|
||||||
|
|
||||||
|
protected static final Logger logger = Logger.getLogger(SncpRemoteInfo.class.getSimpleName());
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
|
|
||||||
@@ -34,40 +40,43 @@ public final class SncpRemoteInfo<T extends Service> {
|
|||||||
|
|
||||||
protected final Uint128 serviceid;
|
protected final Uint128 serviceid;
|
||||||
|
|
||||||
|
protected final String resourceid;
|
||||||
|
|
||||||
protected final int serviceVersion;
|
protected final int serviceVersion;
|
||||||
|
|
||||||
protected final SncpRemoteAction[] actions;
|
protected final SncpRemoteAction[] actions;
|
||||||
|
|
||||||
//MQ模式下此字段才有值
|
|
||||||
protected final String topic;
|
|
||||||
|
|
||||||
//默认值: BsonConvert.root()
|
|
||||||
protected final Convert convert;
|
|
||||||
|
|
||||||
//非MQ模式下此字段才有值
|
//非MQ模式下此字段才有值
|
||||||
protected final SncpRpcGroups sncpRpcGroups;
|
protected final SncpRpcGroups sncpRpcGroups;
|
||||||
|
|
||||||
//非MQ模式下此字段才有值
|
//非MQ模式下此字段才有值
|
||||||
protected final SncpClient sncpClient;
|
protected final SncpClient sncpClient;
|
||||||
|
|
||||||
|
//非MQ模式下此字段才有值, 可能为null
|
||||||
|
protected String remoteGroup;
|
||||||
|
|
||||||
|
//非MQ模式下此字段才有值, 可能为null
|
||||||
|
protected Set<InetSocketAddress> remoteAddresses;
|
||||||
|
|
||||||
|
//默认值: BsonConvert.root()
|
||||||
|
protected final Convert convert;
|
||||||
|
|
||||||
|
//MQ模式下此字段才有值
|
||||||
|
protected final String topic;
|
||||||
|
|
||||||
//MQ模式下此字段才有值
|
//MQ模式下此字段才有值
|
||||||
protected final MessageAgent messageAgent;
|
protected final MessageAgent messageAgent;
|
||||||
|
|
||||||
//MQ模式下此字段才有值
|
//MQ模式下此字段才有值
|
||||||
protected final SncpMessageClient messageClient;
|
protected final SncpMessageClient messageClient;
|
||||||
|
|
||||||
//MQ模式下此字段才有值, 可能为null
|
SncpRemoteInfo(String resourceName, Class<T> resourceType, Class<T> serviceImplClass, Convert convert,
|
||||||
protected String remoteGroup;
|
|
||||||
|
|
||||||
//MQ模式下此字段才有值, 可能为null
|
|
||||||
protected Set<InetSocketAddress> remoteAddresses;
|
|
||||||
|
|
||||||
SncpRemoteInfo(String resourceName, Class<T> resourceServiceType, Class<T> serviceImplClass, Convert convert,
|
|
||||||
SncpRpcGroups sncpRpcGroups, SncpClient sncpClient, MessageAgent messageAgent, String remoteGroup) {
|
SncpRpcGroups sncpRpcGroups, SncpClient sncpClient, MessageAgent messageAgent, String remoteGroup) {
|
||||||
Objects.requireNonNull(sncpRpcGroups);
|
Objects.requireNonNull(sncpRpcGroups);
|
||||||
this.name = resourceName;
|
this.name = resourceName;
|
||||||
this.serviceType = resourceServiceType;
|
this.serviceType = resourceType;
|
||||||
this.serviceid = Sncp.serviceid(resourceName, resourceServiceType);
|
this.resourceid = Sncp.resourceid(resourceName, resourceType);
|
||||||
|
this.serviceid = Sncp.serviceid(resourceName, resourceType);
|
||||||
this.convert = convert;
|
this.convert = convert;
|
||||||
this.serviceVersion = 0;
|
this.serviceVersion = 0;
|
||||||
this.sncpRpcGroups = sncpRpcGroups;
|
this.sncpRpcGroups = sncpRpcGroups;
|
||||||
@@ -75,16 +84,149 @@ public final class SncpRemoteInfo<T extends Service> {
|
|||||||
this.messageAgent = messageAgent;
|
this.messageAgent = messageAgent;
|
||||||
this.remoteGroup = remoteGroup;
|
this.remoteGroup = remoteGroup;
|
||||||
this.messageClient = messageAgent == null ? null : messageAgent.getSncpMessageClient();
|
this.messageClient = messageAgent == null ? null : messageAgent.getSncpMessageClient();
|
||||||
this.topic = messageAgent == null ? null : messageAgent.generateSncpReqTopic(resourceName, resourceServiceType);
|
this.topic = messageAgent == null ? null : messageAgent.generateSncpReqTopic(resourceName, resourceType);
|
||||||
|
|
||||||
final List<SncpRemoteAction> serviceActions = new ArrayList<>();
|
final List<SncpRemoteAction> serviceActions = new ArrayList<>();
|
||||||
for (Map.Entry<Uint128, Method> en : loadMethodActions(resourceServiceType).entrySet()) {
|
for (Map.Entry<Uint128, Method> en : loadMethodActions(resourceType).entrySet()) {
|
||||||
serviceActions.add(new SncpRemoteAction(serviceImplClass, en.getValue(), serviceid, en.getKey()));
|
serviceActions.add(new SncpRemoteAction(serviceImplClass, en.getValue(), serviceid, en.getKey()));
|
||||||
}
|
}
|
||||||
this.actions = serviceActions.toArray(new SncpRemoteAction[serviceActions.size()]);
|
this.actions = serviceActions.toArray(new SncpRemoteAction[serviceActions.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InetSocketAddress nextRemoteAddress() {
|
//由远程模式的DyncRemoveService调用
|
||||||
|
public <T> T remote(final int index, final Object... params) {
|
||||||
|
final SncpRemoteAction action = this.actions[index];
|
||||||
|
CompletionHandler callbackHandler = null;
|
||||||
|
Object callbackHandlerAttach = null;
|
||||||
|
if (action.paramHandlerIndex >= 0) {
|
||||||
|
callbackHandler = (CompletionHandler) params[action.paramHandlerIndex];
|
||||||
|
params[action.paramHandlerIndex] = null;
|
||||||
|
if (action.paramHandlerAttachIndex >= 0) {
|
||||||
|
callbackHandlerAttach = params[action.paramHandlerAttachIndex];
|
||||||
|
params[action.paramHandlerAttachIndex] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final CompletableFuture<byte[]> future = remote(action, Traces.currTraceid(), params);
|
||||||
|
if (action.paramHandlerIndex >= 0) { //参数中存在CompletionHandler
|
||||||
|
final CompletionHandler handler = callbackHandler;
|
||||||
|
final Object attach = callbackHandlerAttach;
|
||||||
|
if (handler == null) { //传入的CompletionHandler参数为null
|
||||||
|
future.join();
|
||||||
|
} else {
|
||||||
|
future.whenComplete((v, t) -> {
|
||||||
|
if (t == null) {
|
||||||
|
//v,length-1为了读掉(byte)0
|
||||||
|
handler.completed(v == null ? null : convert.convertFrom(action.paramHandlerResultType, v, 1, v.length - 1), attach);
|
||||||
|
} else {
|
||||||
|
handler.failed(t, attach);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (action.returnFutureClass != null) { //返回类型为CompletableFuture
|
||||||
|
if (action.returnFutureClass == CompletableFuture.class) {
|
||||||
|
//v,length-1为了读掉(byte)0
|
||||||
|
return (T) future.thenApply(v -> v == null ? null : convert.convertFrom(action.returnFutureResultType, v, 1, v.length - 1));
|
||||||
|
} else {
|
||||||
|
final CompletableFuture returnFuture = action.returnFutureCreator.create();
|
||||||
|
future.whenComplete((v, t) -> {
|
||||||
|
if (t == null) {
|
||||||
|
//v,length-1为了读掉(byte)0
|
||||||
|
returnFuture.complete(v == null ? null : convert.convertFrom(action.returnFutureResultType, v, 1, v.length - 1));
|
||||||
|
} else {
|
||||||
|
returnFuture.completeExceptionally(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (T) returnFuture;
|
||||||
|
}
|
||||||
|
} else if (action.returnObjectType != null) { //返回类型为JavaBean
|
||||||
|
//v,length-1为了读掉(byte)0
|
||||||
|
return (T) future.thenApply(v -> v == null ? null : convert.convertFrom(action.returnObjectType, v, 1, v.length - 1)).join();
|
||||||
|
} else { //返回类型为void
|
||||||
|
future.join();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<byte[]> remote(final SncpRemoteAction action, final String traceid, final Object[] params) {
|
||||||
|
if (messageAgent != null) {
|
||||||
|
return remoteMessage(action, traceid, params);
|
||||||
|
} else {
|
||||||
|
return remoteClient(action, traceid, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MQ模式RPC
|
||||||
|
protected CompletableFuture<byte[]> remoteMessage(final SncpRemoteAction action, final String traceid, final Object[] params) {
|
||||||
|
final SncpClientRequest request = createSncpClientRequest(action, this.sncpClient.clientSncpAddress, traceid, params);
|
||||||
|
String targetTopic = action.paramTopicTargetIndex >= 0 ? (String) params[action.paramTopicTargetIndex] : this.topic;
|
||||||
|
if (targetTopic == null) {
|
||||||
|
targetTopic = this.topic;
|
||||||
|
}
|
||||||
|
ByteArray array = new ByteArray();
|
||||||
|
request.writeTo(null, array);
|
||||||
|
MessageRecord message = messageClient.createMessageRecord(targetTopic, null, array.getBytes());
|
||||||
|
final String tt = targetTopic;
|
||||||
|
if (logger.isLoggable(Level.FINER)) {
|
||||||
|
message.attach(Utility.append(new Object[]{action.actionName()}, params));
|
||||||
|
} else {
|
||||||
|
message.attach(params);
|
||||||
|
}
|
||||||
|
return messageClient.sendMessage(message).thenApply(msg -> {
|
||||||
|
if (msg == null || msg.getContent() == null) {
|
||||||
|
logger.log(Level.SEVERE, action.method + " sncp mq(params: " + JsonConvert.root().convertTo(params) + ", message: " + message + ") deal error, this.topic = " + this.topic + ", targetTopic = " + tt + ", result = " + msg);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ByteBuffer buffer = ByteBuffer.wrap(msg.getContent());
|
||||||
|
SncpHeader header = new SncpHeader();
|
||||||
|
int headerSize = header.read(buffer);
|
||||||
|
if (headerSize != HEADER_SIZE) {
|
||||||
|
throw new SncpException("sncp header length must be " + HEADER_SIZE + ", but is " + headerSize);
|
||||||
|
}
|
||||||
|
if (!header.checkValid(action.header)) {
|
||||||
|
throw new SncpException("sncp header error, response-header:" + action.header + "+, response-header:" + header);
|
||||||
|
}
|
||||||
|
final int retcode = header.getRetcode();
|
||||||
|
if (retcode != 0) {
|
||||||
|
logger.log(Level.SEVERE, action.method + " sncp (params: " + JsonConvert.root().convertTo(params) + ") deal error (retcode=" + retcode + ", retinfo=" + SncpResponse.getRetCodeInfo(retcode) + "), params=" + JsonConvert.root().convertTo(params));
|
||||||
|
throw new SncpException("remote service(" + action.method + ") deal error (retcode=" + retcode + ", retinfo=" + SncpResponse.getRetCodeInfo(retcode) + ")");
|
||||||
|
}
|
||||||
|
final int respBodyLength = header.getBodyLength();
|
||||||
|
byte[] body = new byte[respBodyLength];
|
||||||
|
buffer.get(body, 0, respBodyLength);
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Client模式RPC
|
||||||
|
protected CompletableFuture<byte[]> remoteClient(final SncpRemoteAction action, final String traceid, final Object[] params) {
|
||||||
|
final SncpClient client = this.sncpClient;
|
||||||
|
final SncpClientRequest request = createSncpClientRequest(action, client.clientSncpAddress, traceid, params);
|
||||||
|
final SocketAddress addr = action.paramAddressTargetIndex >= 0 ? (SocketAddress) params[action.paramAddressTargetIndex] : nextRemoteAddress();
|
||||||
|
return client.connect(addr).thenCompose(conn -> client.writeChannel(conn, request).thenApply(rs -> rs.getBodyContent()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SncpClientRequest createSncpClientRequest(final SncpRemoteAction action, final InetSocketAddress clientSncpAddress, final String traceid, final Object[] params) {
|
||||||
|
final Type[] myParamTypes = action.paramTypes;
|
||||||
|
final Class[] myParamClass = action.paramClasses;
|
||||||
|
if (action.paramAddressSourceIndex >= 0) {
|
||||||
|
params[action.paramAddressSourceIndex] = clientSncpAddress;
|
||||||
|
}
|
||||||
|
final long seqid = System.nanoTime();
|
||||||
|
byte[] body = null;
|
||||||
|
if (myParamTypes.length > 0) {
|
||||||
|
Writer writer = convert.pollWriter();
|
||||||
|
for (int i = 0; i < params.length; i++) { //service方法的参数
|
||||||
|
convert.convertTo(writer, CompletionHandler.class.isAssignableFrom(myParamClass[i]) ? CompletionHandler.class : myParamTypes[i], params[i]);
|
||||||
|
}
|
||||||
|
body = ((ByteTuple) writer).toArray();
|
||||||
|
convert.offerWriter(writer);
|
||||||
|
}
|
||||||
|
final SncpClientRequest requet = new SncpClientRequest();
|
||||||
|
requet.prepare(action.header, seqid, traceid, body);
|
||||||
|
return requet;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected InetSocketAddress nextRemoteAddress() {
|
||||||
SncpRpcGroup srg = sncpRpcGroups.getSncpRpcGroup(remoteGroup);
|
SncpRpcGroup srg = sncpRpcGroups.getSncpRpcGroup(remoteGroup);
|
||||||
if (srg != null) {
|
if (srg != null) {
|
||||||
Set<InetSocketAddress> addrs = srg.getAddresses();
|
Set<InetSocketAddress> addrs = srg.getAddresses();
|
||||||
@@ -98,19 +240,6 @@ public final class SncpRemoteInfo<T extends Service> {
|
|||||||
throw new SncpException("Not found SocketAddress by remoteGroup = " + remoteGroup);
|
throw new SncpException("Not found SocketAddress by remoteGroup = " + remoteGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
//由远程模式的DyncRemoveService调用
|
|
||||||
public <T> T remote(final int index, final Object... params) {
|
|
||||||
if (messageAgent != null) {
|
|
||||||
return remoteMessage(index, params);
|
|
||||||
} else {
|
|
||||||
return sncpClient.remote(this, index, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T remoteMessage(final int index, final Object[] params) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
InetSocketAddress clientSncpAddress = sncpClient == null ? null : sncpClient.getClientSncpAddress();
|
InetSocketAddress clientSncpAddress = sncpClient == null ? null : sncpClient.getClientSncpAddress();
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.util;
|
package org.redkale.util;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 简单的byte[]数据接口。
|
* 简单的byte[]数据接口。
|
||||||
*
|
*
|
||||||
@@ -21,4 +23,9 @@ public interface ByteTuple {
|
|||||||
public int offset();
|
public int offset();
|
||||||
|
|
||||||
public int length();
|
public int length();
|
||||||
|
|
||||||
|
default byte[] toArray() {
|
||||||
|
int o = offset();
|
||||||
|
return Arrays.copyOfRange(content(), o, o + length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ public class SncpClientCodecTest {
|
|||||||
SncpHeader header = new SncpHeader(sncpAddress, Uint128.ZERO, Uint128.ZERO);
|
SncpHeader header = new SncpHeader(sncpAddress, Uint128.ZERO, Uint128.ZERO);
|
||||||
SncpClientRequest request = new SncpClientRequest();
|
SncpClientRequest request = new SncpClientRequest();
|
||||||
ByteArray writeArray = new ByteArray();
|
ByteArray writeArray = new ByteArray();
|
||||||
request.prepare(header, 1, "", new ByteArray().putPlaceholder(20));
|
request.prepare(header, 1, "", new byte[20]);
|
||||||
System.out.println("request.1 = " + request);
|
System.out.println("request.1 = " + request);
|
||||||
writeArray.put(new byte[SncpHeader.HEADER_SIZE]);
|
writeArray.put(new byte[SncpHeader.HEADER_SIZE]);
|
||||||
request.writeTo(conn, writeArray);
|
request.writeTo(conn, writeArray);
|
||||||
request.prepare(header, 2, "", new ByteArray().putPlaceholder(25));
|
request.prepare(header, 2, "", new byte[25]);
|
||||||
System.out.println("request.2 = " + request);
|
System.out.println("request.2 = " + request);
|
||||||
writeArray.put(new byte[SncpHeader.HEADER_SIZE]);
|
writeArray.put(new byte[SncpHeader.HEADER_SIZE]);
|
||||||
request.writeTo(conn, writeArray);
|
request.writeTo(conn, writeArray);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class SncpTest {
|
|||||||
|
|
||||||
private static int port2 = 4240;
|
private static int port2 = 4240;
|
||||||
|
|
||||||
private static final String protocol = "SNCP.UDP";
|
private static final String protocol = "SNCP.TCP"; // TCP UDP
|
||||||
|
|
||||||
private static final int clientCapacity = protocol.endsWith(".UDP") ? AsyncGroup.UDP_BUFFER_CAPACITY : 8192;
|
private static final int clientCapacity = protocol.endsWith(".UDP") ? AsyncGroup.UDP_BUFFER_CAPACITY : 8192;
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public class SncpTest {
|
|||||||
System.out.println("bean: " + callbean);
|
System.out.println("bean: " + callbean);
|
||||||
System.out.println("\r\n\r\n\r\n\r\n---------------------------------------------------");
|
System.out.println("\r\n\r\n\r\n\r\n---------------------------------------------------");
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
final int count = 10;
|
final int count = 40;
|
||||||
final CountDownLatch cld = new CountDownLatch(count);
|
final CountDownLatch cld = new CountDownLatch(count);
|
||||||
final AtomicInteger ai = new AtomicInteger();
|
final AtomicInteger ai = new AtomicInteger();
|
||||||
long s = System.currentTimeMillis();
|
long s = System.currentTimeMillis();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class SncpTestServiceImpl implements SncpTestIService {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
System.out.println(Thread.currentThread().getName() + " sleep 200ms后运行了异步方法-----------queryResultAsync方法");
|
System.out.println(Thread.currentThread().getName() + " sleep 200ms后运行了异步方法-----------queryResultAsync方法");
|
||||||
future.complete("异步result: " + bean);
|
future.complete("异步 result: " + bean);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user