在客户端需要依赖服务端的jar包和类,在客户端也新建和服务端一样的接口和实现类
consumer.xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="hehe_consumer" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<!--<dubbo:registry address="multicast://127.0.0.1:1234" />-->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!--<dubbo:dubooTestDemo address="127.0.0.1:20880"></dubbo:registry>-->
<!-- 生成远程服务代理,可以像使用本地bean一样使用demoService -->
<dubbo:reference id="dubooTestDemo" group="jd" version="1.0" timeout="2000" interface="com.jd.service.DubboTestService"/>
<dubbo:reference id="registerService" interface="com.jd.service.RegisterService"/>
</beans>
新建类DubboConsumer 内容有如下,这种方式是集成spring去掉用服务端接口
import com.alibaba.fastjson.JSON;
import com.jd.domain.ResponseMessage;
import com.jd.domain.User;
import com.jd.service.DubboTestService;
import com.jd.service.RegisterService;
import javafx.application.Application;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import javax.xml.ws.spi.Invoker;
import java.io.IOException;
/**
* Created by Administrator on 2017/9/2 0002.
*/
public class DubboConsumer {
public static void main(String[] args) throws IOException {
//classpath去运行时的环境去找这个文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo/consumer.xml");
//如果consumer.xml不放在resources下,可以使用文件路径FileSystemXmlApplication这个接口,填写绝对路径
//ApplicationContext context1 = new FileSystemXmlApplicationContext("D:\\dubboController\\xml\\consumer.xml");
DubboTestService dubboTestService = (DubboTestService)context.getBean("dubooTestDemo");
String name = dubboTestService.getName();
System.out.println(name);
dubboTestService.say();
//返回的是一个对象,对象输出必须得转化成字符串形式,用fastjson
ResponseMessage responseMessage = dubboTestService.getUserById(55);
System.out.print("responseMessage"+ JSON.toJSONString(responseMessage));
RegisterService registerService = (RegisterService)context.getBean("registerService");
User user = new User();
user.setUsername("niu");
//{"username":"niuniu"}
registerService.registerUser(user);
}
}
第二种方法用泛化的方式去掉用
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.MethodConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.fastjson.JSON;
import com.jd.service.DubboTestService;
import com.jd.service.RegisterService;
import javafx.application.Application;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017/9/3 0003.
*/
public class GenericConsumer {
//api调用方式
@Test
public void genericTest() {
//对应配置文件中的<dubbo:application name="hehe_consumer" />
ApplicationConfig application = new ApplicationConfig();
application.setName("xixi");
// 对应配置文件中的暴露中心链接地址
RegistryConfig registry = new RegistryConfig();
registry.setAddress("multicast://224.5.6.7:1234");
// registry.setUsername("aaa");
// registry.setPassword("bbb");
// 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
// 引用远程服务
// 服务实现,对应配置中的 <dubbo:reference id="dubooTestDemo" group="jd" version="1.0" timeout="2000" interface="com.jd.service.DubboTestService"/>
ReferenceConfig<DubboTestService> reference = new ReferenceConfig<DubboTestService>();// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
reference.setApplication(application);
reference.setRegistry(registry);// 多个注册中心可以用setRegistries()
reference.setInterface(DubboTestService.class);
reference.setVersion("1.0");
reference.setGroup("jd");
reference.setTimeout(2000);
// reference.setUrl("dubbo://127.0.0.1:20880/com.longteng.service.DubboTestService?application=xixi_provider&callbacks=10000&connect.timeout=10000&method=getUsers");
// 和本地bean一样使用xxxService
//方法的设置
List<MethodConfig> methods = new ArrayList<MethodConfig>();
MethodConfig method = new MethodConfig();
method.setName("getName");
method.setTimeout(10000);
//方法重试
method.setRetries(0);
methods.add(method);
reference.setMethods(methods);// 设置方法级配置
//相当于api的方式调用
//长连接,一个接口只需要做一次就好了 get相当于spring里的getbean 那一段一样,和spring那个相对应理解
DubboTestService xxxService = reference.get();// 注意:此代理对象内部封装了所有通讯细节,对
Object o = "jiaou";
System.out.println(JSON.toJSONString(xxxService.getUserById(1)));
System.out.println(JSON.toJSONString(xxxService.sayHello("jiaou")));
System.out.println();
}
}
第三种方式用telnet去调用
com.test.DemoService
查看服务中的接口
dubbo>ls com.test.DemoService
queryDemoPageList
insertDemolist
uploadDemoList
deleteDemolist
ls
(list services and methods)
ls
显示服务列表。
ls -l
显示服务详细信息列表。
ls XxxService
显示服务的方法列表。
ls -l XxxService
显示服务的方法详细信息列表。
3.调用服务接口
调用接口时,以JSON格式传入参数(这点很方便 :-D),然后打印返回值和所用时间。
dubbo>invoke com.test.DemoService.queryDemoPageList({"id":"100"}, 1, 2)
{"totalCount":1,"data":[{date":"2011-03-23 14:10:32","name":"张三","keyword":null}]}
elapsed: 10 ms.
invoke
invoke XxxService.xxxMethod({"prop": "value"})
调用服务的方法。
invoke xxxMethod({"prop": "value"})
写代码作为TelnetSocket
/**
* Created by Administrator on 2017/9/3 0003.
*/
import org.apache.log4j.Logger;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TelnetSocket {
private final static Logger LOGGER = Logger.getLogger(TelnetSocket.class);
/**
* socket函数
*/
private Socket socket;
/**
* 换行符
*/
private final static String LINE_SEPARATOR = System.getProperty("line.separator");
/**
* 默认读字符编码
*/
private String readEncoding = "UTF-8";
/**
* 默认写字符编码
*/
private String writeEncoding = "UTF-8";
/**
* DubboTelnetClient 构造
*
* @param ip
* ip地址
* @param port
* 端口
* @throws java.net.UnknownHostException
* @throws java.io.IOException
*/
public TelnetSocket(String ip, int port) throws UnknownHostException,
IOException {
this.socket = new Socket(ip, port);
}
/**
* DubboTelnetClient 构造
*
* @param ip
* ip地址
* @param port
* 端口
* @param connTimeout
* 连接超时时间超时时间
* @throws java.net.UnknownHostException
* @throws java.io.IOException
*/
public TelnetSocket(String ip, int port, int connTimeout)
throws UnknownHostException, IOException {
this(ip, port, connTimeout, 5000);
}
public boolean isConnected(){
return socket.isConnected();
}
/**
* DubboTelnetClient 构造
*
* @param ip
* ip地址
* @param port
* 端口
* @param connTimeout
* 连接超时时间
* @param soTimeout
* 读取超时时间
* @throws java.net.UnknownHostException
* @throws java.io.IOException
*/
public TelnetSocket(String ip, int port, int connTimeout, int soTimeout)
throws UnknownHostException, IOException {
try {
this.socket = new Socket();
socket.setSoTimeout(soTimeout);
socket.connect(new InetSocketAddress(ip, port), connTimeout);
} catch (Exception e) {
LOGGER.error("连接"+ip+":"+port+"异常"+e.getMessage(), e);
}
}
/**
* 发送消息
*
* @param msg
* 消息
* @param times
* 读取次数(即遇到dubbo>结尾代表一次)
* @return 返回消息
* @throws java.io.IOException
*/
public String send(String msg, int times) throws IOException {
String result = "";
InputStream in = null;
OutputStream out = null;
ByteArrayOutputStream baout = null;
try {
// 初始化通道
//发送消息
in = socket.getInputStream();
out = socket.getOutputStream();
// 发送请求
out.write(msg.getBytes(writeEncoding));
out.write(LINE_SEPARATOR.getBytes(writeEncoding));
out.flush(); //刷新缓存
//接收消息
baout = new ByteArrayOutputStream();
// 解析得到的响应
StringBuffer sb = new StringBuffer();
byte[] bs = new byte[1024];
int len = 0;
int i = 0;
while (i < 1024 && (len = in.read(bs)) != -1) {
//if (i > 1024) { // 防止无限循环 最多取 1M的数据
// break;
//}
String data = new String(bs, 0, len, readEncoding);
baout.write(bs, 0, len);
sb.append(data);
String last = sb.substring(sb.length()-6);
if (last.endsWith("jsf>") || "dubbo>".equals(last) || "lnet> ".equals(last)) {
if (--times < 1) {
break; // 读到这个就断开连接返回
}
}
i++;
}
result = new String(baout.toByteArray(), readEncoding);
return result;
} catch (Exception e) {
LOGGER.error("执行socket命令"+msg+"结束, 结果为"+e.getMessage(), e);
}finally {
if(baout!=null){
baout.close();
}
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
return result;
}
/**
* 发送消息
*
* @param msg
* 消息
* @return 返回消息
* @throws java.io.IOException
*/
public String send(String msg) throws IOException {
int time = 1;
if (msg.startsWith("count")) {
time = 2; // count命令会返回2次dubbo
} else if (msg.startsWith("trace")) {
String[] cmds = msg.split("\\s+"); // trace几次返回几次
time = cmds.length > 2 ? Integer.valueOf(cmds[cmds.length - 1]
.trim()) : 1;
}
return send(msg, time);
}
/**
* 发送消息
*
* @param msg
* 消息
* @return 返回消息
* @throws java.io.IOException
* @deprecated use {@link #send(String)}
*/
public String sendOld(String msg) throws IOException {
String result = "";
BufferedReader in = null;
PrintWriter out = null;
try {
// 初始化通道
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// 发送请求
out.println(msg);
out.flush();
// 解析得到的响应
StringBuffer sb = new StringBuffer();
char[] cbuf = new char[10240];
in.read(cbuf);
/*try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
sb.append(cbuf, 0, cbuf.length);
result = sb.toString();
return result;
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
}
/**
* 关闭连接
*/
public void close() {
try {
if (socket != null && !socket.isClosed())
socket.close();
} catch (IOException e) {
// ignore
// e.printStackTrace();
}
}
/**
* @return the readEncoding
*/
public String getReadEncoding() {
return readEncoding;
}
/**
* @param readEncoding the readEncoding to set
*/
public void setReadEncoding(String readEncoding) {
this.readEncoding = readEncoding;
}
/**
* @return the writeEncoding
*/
public String getWriteEncoding() {
return writeEncoding;
}
/**
* @param writeEncoding the writeEncoding to set
*/
public void setWriteEncoding(String writeEncoding) {
this.writeEncoding = writeEncoding;
}
public static void main(String[] args) {
String[] cmds = new String[] { "invoke com.jd.ecc.delivery.service.AddressBaseService.getAddressesByCode(\"3301\")" };
// String[] cmds = new String[] { "ls -l", "count com.jd.testsaf.HelloService", "trace com.jd.testsaf.HelloService"};
TelnetSocket client = null;
long time0 = System.currentTimeMillis();
try {
for (int i = 0; i < cmds.length; i++) {
client = new TelnetSocket("192.168.192.153", 32000,5000,30000);
// client = new DubboTelnetClient("10.12.120.121", 20880,5000);
client.setReadEncoding("gbk");
String res = client.send(cmds[i]);
System.out.println("命令:" + cmds[i] + " 返回");
System.out.println(res);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (client != null) {
client.close();
}
}
long time1 = System.currentTimeMillis();
System.out.println("耗时:" + (time1 - time0) + "ms");
}
}
TelnetConsumer
import java.io.IOException;
/**
* Created by Administrator on 2017/9/3 0003.
*/
public class TelnetConsumer {
public static void main(String[] args) throws IOException {
String ip = "127.0.0.1";
int port = 20880;
TelnetSocket telnetSocket = new TelnetSocket(ip,port);
String interfaceName = "com.jd.service.DubboTestService";
String methodName = "getUserById";
String param = "0";
//invoke com.jd.service.DubboTestService.getUserById(0) 命令的组装
String cmd = "invoke "+interfaceName+"."+methodName+"(\""+param+"\")";
System.out.print(cmd);
String result = telnetSocket.send(cmd);
System.out.print("返回的结果:"+result);
}
}