blob: 87beb4fc58d553ff2aa60c5b6e16adefb3e3cde5 [file] [log] [blame]
/*
* Copyright 1999-2011 Alibaba Group.
*
* 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.alibaba.dubbo.rpc.protocol.hessian;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.remoting.http.HttpBinder;
import com.alibaba.dubbo.remoting.http.HttpHandler;
import com.alibaba.dubbo.remoting.http.HttpServer;
import com.alibaba.dubbo.rpc.Exporter;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
/**
* http rpc support.
*
* @author qianlei
*/
public class HessianProtocol extends AbstractProtocol {
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
private HttpBinder httpTransporter;
private ProxyFactory proxyFactory;
public void setHttpTransporter(HttpBinder httpTransporter) {
this.httpTransporter = httpTransporter;
}
public void setProxyFactory(ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
}
public int getDefaultPort() {
return 80;
}
private class HessianHandler implements HttpHandler {
public void handle(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String uri = request.getRequestURI();
HessianRpcExporter<?> exporter = (HessianRpcExporter<?>) exporterMap.get(uri);
exporter.handle(request, response);
}
}
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
final URL url = invoker.getUrl();
final String uri = url.getAbsolutePath(); // service uri also exporter cache key.
String addr = url.getIp() + ":" + url.getPort();
HttpServer server = serverMap.get(addr);
if (server == null) {
server = httpTransporter.bind(url, new HessianHandler());
serverMap.put(addr, server);
}
HessianRpcExporter<T> exporter = new HessianRpcExporter<T>(invoker, proxyFactory) {
public void unexport() {
super.unexport();
exporterMap.remove(uri);
}
};
exporterMap.put(uri, exporter);
return exporter;
}
public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
Invoker<T> invoker = new HessianRpcInvoker<T>(serviceType, url, proxyFactory);
invokers.add(invoker);
return invoker;
}
public void destroy() {
super.destroy();
for (String key : new ArrayList<String>(serverMap.keySet())) {
HttpServer server = serverMap.remove(key);
if (server != null) {
try {
if (logger.isInfoEnabled()) {
logger.info("Close hessian server " + server.getUrl());
}
server.close();
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
}
}
}
}