use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.
the class Service method asyncSendEthereumMessage.
public void asyncSendEthereumMessage(EthereumRequest request, EthereumResponseCallback callback) {
logger.debug("处理Ethereum请求: " + request.getMessageID());
Boolean sended = false;
EthereumMessage ethereumMessage = new EthereumMessage();
ethereumMessage.setSeq(request.getMessageID());
ethereumMessage.setResult(0);
ethereumMessage.setType((short) 0x12);
ethereumMessage.setData(request.getContent().getBytes());
// 选取发送节点
try {
ChannelConnections fromChannelConnections = allChannelConnections.get(orgID);
if (fromChannelConnections == null) {
// 没有找到对应的链
// 返回错误
logger.error("没有找到本机构:{}", orgID);
throw new Exception("未找到本机构");
}
ChannelHandlerContext ctx = fromChannelConnections.randomNetworkConnection();
ByteBuf out = ctx.alloc().buffer();
ethereumMessage.writeHeader(out);
ethereumMessage.writeExtra(out);
seq2Callback.put(request.getMessageID(), callback);
if (request.getTimeout() > 0) {
// ethereum名字可能会搞混,换成channel
final EthereumResponseCallback callbackInner = callback;
callback.setTimeout(timeoutHandler.newTimeout(new TimerTask() {
EthereumResponseCallback _callback = callbackInner;
@Override
public void run(Timeout timeout) throws Exception {
// 处理超时逻辑
_callback.onTimeout();
}
}, request.getTimeout(), TimeUnit.MILLISECONDS));
}
ctx.writeAndFlush(out);
logger.debug("发送Ethereum消息至 " + ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress() + ":" + ((SocketChannel) ctx.channel()).remoteAddress().getPort() + " 成功");
sended = true;
} catch (Exception e) {
logger.error("系统错误", e);
EthereumResponse response = new EthereumResponse();
response.setErrorCode(-1);
response.setErrorMessage("系统错误");
response.setContent("");
response.setMessageID(request.getMessageID());
if (callback.getTimeout() != null) {
callback.getTimeout().cancel();
}
callback.onResponse(response);
}
}
use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.
the class ChannelConnections method startListen.
public void startListen(Integer port) {
if (running) {
logger.debug("服务已启动");
return;
}
logger.debug("初始化connections listen");
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
final ChannelConnections selfService = this;
final ThreadPoolTaskExecutor selfThreadPool = threadPool;
try {
serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource keystoreResource = resolver.getResource(getClientKeystorePath());
Resource caResource = resolver.getResource(getCaCertPath());
ks.load(keystoreResource.getInputStream(), getKeystorePassWord().toCharArray());
/*
* 每次连接使用新的handler
* 连接信息从socketChannel中获取
*/
ChannelHandler handler = new ChannelHandler();
handler.setConnections(selfService);
handler.setIsServer(true);
handler.setThreadPool(selfThreadPool);
SslContext sslCtx = SslContextBuilder.forServer((PrivateKey) ks.getKey("client", getClientCertPassWord().toCharArray()), (X509Certificate) ks.getCertificate("client")).trustManager(caResource.getFile()).build();
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()), new LengthFieldBasedFrameDecoder(1024 * 1024 * 4, 0, 4, -4, 0), new IdleStateHandler(idleTimeout, idleTimeout, idleTimeout, TimeUnit.MILLISECONDS), handler);
}
});
ChannelFuture future = serverBootstrap.bind(port);
future.get();
running = true;
} catch (Exception e) {
logger.error("系统错误", e);
}
}
use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.
the class ChannelHandler method channelRead.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
final ChannelHandlerContext ctxF = ctx;
final ByteBuf in = (ByteBuf) msg;
logger.trace("接收消息,来自" + host + ":" + port + " in:" + in.readableBytes());
logger.trace("threadPool:{}", threadPool == null);
try {
if (threadPool == null) {
connections.onReceiveMessage(ctx, in);
} else {
threadPool.execute(new Runnable() {
@Override
public void run() {
connections.onReceiveMessage(ctxF, in);
}
});
}
} catch (RejectedExecutionException e) {
logger.error("线程池已满,拒绝请求", e);
}
}
use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.
the class ChannelHandler method channelActive.
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
try {
// 已连上,获取ip信息
String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
logger.debug("已成功连接[" + host + "]:[" + String.valueOf(port) + "]," + String.valueOf(ctx.channel().isActive()));
if (isServer) {
logger.debug("server接收新连接: {}:{}", host, port);
// 将此新连接增加到connections
ConnectionInfo info = new ConnectionInfo();
info.setHost(host);
info.setPort(port);
connections.getConnections().add(info);
connections.setNetworkConnectionByHost(info.getHost(), info.getPort(), ctx);
connections.getCallback().onConnect(ctx);
} else {
// 更新ctx信息
ChannelHandlerContext connection = connections.getNetworkConnectionByHost(host, port);
if (connection != null && connection.channel().isActive()) {
logger.debug("连接已存在且有效 关闭重连: {}:{}", host, port);
ctx.channel().disconnect();
ctx.channel().close();
} else {
logger.debug("client成功连接 {}:{}", host, port);
connections.setNetworkConnectionByHost(host, port, ctx);
connections.getCallback().onConnect(ctx);
}
}
} catch (Exception e) {
logger.error("系统错误", e);
}
}
use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.
the class Server method onLocalMessage.
public void onLocalMessage(ChannelHandlerContext ctx, Message message) {
try {
logger.debug("处理来自SDK请求: " + message.getSeq());
ChannelHandlerContext remoteCtx = null;
ConnectionPair pair = seq2Connections.get(message.getSeq());
if (pair != null) {
// 已有这个seq,发往远端的响应
logger.debug("已有seq");
// 发送到远端的响应
remoteCtx = pair.remoteConnection;
if (message.getType() != 0x31) {
pair.localConnection = ctx;
}
ByteBuf out = remoteCtx.alloc().buffer();
message.writeHeader(out);
message.writeExtra(out);
logger.debug("消息发送至:{}:{}", ((SocketChannel) remoteCtx.channel()).remoteAddress().getAddress().getHostAddress(), ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
remoteCtx.writeAndFlush(out);
} else {
pair = new ConnectionPair();
pair.localConnection = ctx;
pair.setServer(this);
pair.setMessage(message);
// 本地发往远程的消息,如果是链上链下,需要按给定的nodeID发
if (message.getType() == 0x20 || message.getType() == 0x21) {
// 获取nodeID
logger.debug("链上链下消息一期 指定目的地");
if (message.getData().length < 256) {
logger.error("错误的channel消息 长度不足256:{}", message.getData().length);
}
// 获取nodeID对应的连接,检查可用性
String nodeID = new String(message.getData(), 128, 128);
logger.debug("转发至:{}", nodeID, message.getData());
for (ConnectionInfo conn : remoteConnections.getConnections()) {
if (conn.getNodeID().equals(nodeID)) {
remoteCtx = remoteConnections.getNetworkConnectionByHost(conn.getHost(), conn.getPort());
pair.remoteConnection = remoteCtx;
break;
}
}
if (remoteCtx == null || !remoteCtx.channel().isActive()) {
// 找不到连接,错误
logger.error("发送连接异常,返回错误99");
if (message.getType() == 0x20 || message.getType() == 0x21) {
message.setType((short) 0x21);
} else {
message.setType((short) 0x31);
}
message.setResult(99);
ByteBuf out = ctx.alloc().buffer();
message.writeHeader(out);
message.writeExtra(out);
ctx.writeAndFlush(out);
return;
}
ByteBuf out = remoteCtx.alloc().buffer();
message.writeHeader(out);
message.writeExtra(out);
logger.debug("消息发送至:{}:{}", ((SocketChannel) remoteCtx.channel()).remoteAddress().getAddress().getHostAddress(), ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
remoteCtx.writeAndFlush(out);
pair.init();
} else {
logger.debug("其它消息,使用ConnectionPair逻辑");
pair.setRemoteChannelConnections(remoteConnections);
List<ConnectionInfo> remoteConnectionInfos = new ArrayList<ConnectionInfo>();
remoteConnectionInfos.addAll(remoteConnections.getConnections());
pair.setRemoteConnectionInfos(remoteConnectionInfos);
seq2Connections.put(message.getSeq(), pair);
pair.init();
pair.retrySendRemoteMessage();
}
}
} catch (Exception e) {
logger.error("系统错误", e);
}
}
Aggregations