com.dinstone.jrpc.transport.mina.MinaConnector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jrpc-transport-mina Show documentation
Show all versions of jrpc-transport-mina Show documentation
Transport implement by mina.
/*
* Copyright (C) 2013~2017 dinstone
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.dinstone.jrpc.transport.mina;
import java.net.InetSocketAddress;
import java.util.Map;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dinstone.jrpc.protocol.Heartbeat;
import com.dinstone.jrpc.protocol.Response;
import com.dinstone.jrpc.protocol.Result;
import com.dinstone.jrpc.protocol.Tick;
import com.dinstone.jrpc.serializer.SerializeType;
import com.dinstone.jrpc.transport.ResultFuture;
import com.dinstone.jrpc.transport.TransportConfig;
/**
* @author guojf
* @version 1.0.0.2013-4-11
*/
public class MinaConnector {
private final class ActiveKeepAliveMessageFactory implements KeepAliveMessageFactory {
private SerializeType serializeType;
public ActiveKeepAliveMessageFactory(SerializeType serializeType) {
this.serializeType = serializeType;
}
@Override
public boolean isResponse(IoSession session, Object message) {
if (message instanceof Heartbeat) {
return true;
}
return false;
}
@Override
public Object getRequest(IoSession session) {
return new Heartbeat(0, serializeType, new Tick());
}
@Override
public boolean isRequest(IoSession session, Object message) {
return false;
}
@Override
public Object getResponse(IoSession session, Object request) {
// HeartbeatPing ping = (HeartbeatPing) request;
// return new HeartbeatPong(ping.getMessageId(), ping.getSerializeType(), new Pong());
return null;
}
}
private static final Logger LOG = LoggerFactory.getLogger(MinaConnector.class);
private NioSocketConnector ioConnector;
public MinaConnector(TransportConfig config) {
initConnector(config);
}
private void initConnector(TransportConfig config) {
// create connector
ioConnector = new NioSocketConnector(1);
ioConnector.setConnectTimeoutMillis(config.getConnectTimeout());
SocketSessionConfig sessionConfig = ioConnector.getSessionConfig();
sessionConfig.setTcpNoDelay(true);
sessionConfig.setReceiveBufferSize(8 * 1024);
sessionConfig.setSendBufferSize(8 * 1024);
DefaultIoFilterChainBuilder chainBuilder = ioConnector.getFilterChain();
final TransportProtocolEncoder encoder = new TransportProtocolEncoder();
final TransportProtocolDecoder decoder = new TransportProtocolDecoder();
encoder.setMaxObjectSize(config.getMaxSize());
decoder.setMaxObjectSize(config.getMaxSize());
// add filter
chainBuilder.addLast("codec", new ProtocolCodecFilter(encoder, decoder));
// add keep alive filter
ActiveKeepAliveMessageFactory messageFactory = new ActiveKeepAliveMessageFactory(config.getSerializeType());
KeepAliveFilter kaFilter = new KeepAliveFilter(messageFactory, IdleStatus.BOTH_IDLE);
kaFilter.setRequestInterval(config.getHeartbeatIntervalSeconds());
kaFilter.setForwardEvent(true);
chainBuilder.addLast("keepAlive", kaFilter);
// set handler
ioConnector.setHandler(new MinaIoHandler());
}
/**
* @param sa
* @return
*/
public IoSession createSession(InetSocketAddress sa) {
// create session
// LOG.debug("create session to {} ", ioConnector.getDefaultRemoteAddress());
// long s = System.currentTimeMillis();
IoSession session = ioConnector.connect(sa).awaitUninterruptibly().getSession();
// long t = System.currentTimeMillis() - s;
LOG.debug("session connect {} to {}", session.getLocalAddress(), session.getRemoteAddress());
return session;
}
public void dispose() {
ioConnector.dispose(false);
}
private class MinaIoHandler extends IoHandlerAdapter {
@Override
public void sessionClosed(IoSession session) throws Exception {
// LOG.debug("Session[{}] is closed", session.getId());
Map futureMap = SessionUtil.getResultFutureMap(session);
if (futureMap != null) {
for (ResultFuture future : futureMap.values()) {
future.setResult(new Result(400, "connection is closed"));
}
}
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
LOG.error("Unhandled Exception", cause);
session.close(true);
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
handle(session, (Response) message);
}
private void handle(IoSession session, Response response) {
Map cfMap = SessionUtil.getResultFutureMap(session);
ResultFuture future = cfMap.remove(response.getMessageId());
if (future != null) {
future.setResult(response.getResult());
}
}
}
public InetSocketAddress getRemoteAddress() {
return ioConnector.getDefaultRemoteAddress();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy