本章要实现两个进程之间的通信也是微服务的一些底层原理
需要的知识技能
- java基础
- Socket
- IO
- TCP,HTTP协议
- 反射
先创建第一个项目为服务项目
Serviec层写的是要被调用类,分别为借口和实现类
ServerBoot是Server的main函数
service的接口
package com.yunhe.server.service;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public interface IorderService {
String getOrder(int orderId,String name);
String getOrderName(String name);
}
Service的实现类,第二个方法本章没有用到
package com.yunhe.server.service.impl;
import com.yunhe.server.service.IorderService;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public class OrderService implements IorderService {
@Override
public String getOrder(int orderId, String name) {
return "订单号:"+orderId+",订单名称:"+name;
}
@Override
public String getOrderName(String name) {
return "订单名称:"+name;
}
}
ServerBoot的内容
package com.yunhe.server;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public class ServerBoot {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
String requestdata = "";
while (true) {
Socket socketServer = serverSocket.accept();
byte[] b = new byte[1];
while (socketServer.getInputStream().read(b) != -1) {
requestdata = requestdata + new String(b);
}
System.out.println("从客户端接收的数据:" + requestdata);
// 以"/r/n"为约定分割
String[] split = requestdata.split("/r/n");
// 将数组的内容解码
String packageName = split[0];
String className = split[1];
String method = split[2];
String argVal = split[3];
Class<?> classObj = null;
try {
// 获取的包和类名找到本地的利用反射实例化
classObj = Class.forName(packageName + "." + className);
Method returnMethod = classObj.getMethod(method, String.class);
String result = (String) returnMethod.invoke(classObj.newInstance(), argVal);
System.out.println("返回给客户端的结果:"+result);
socketServer.getOutputStream().write(result.getBytes(Charset.forName("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
下面写客户端的内容
客户端和服务端接口基本上一样只是增加了SocketUtil的封装类
接口要和服务端定义的一样
package com.yunhe.client.service;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public interface IorderService {
/**
* 服务端地址
*/
String url = "127.0.0.1";
/**
* 远程端口
*/
int port = 8080;
/**
* 远程的包名 /r/n是分割协议
*/
String packageName = "com.yunhe.server.service.impl/r/n";
String getOrder(Integer orderId, String name);
String getOrderName(String name);
}
实现类为了规范把把名称改成了OrderServiceImpl
package com.yunhe.client.service.impl;
import com.yunhe.client.service.IorderService;
import com.yunhe.client.util.SocketUtil;
import java.util.ArrayList;
import java.util.List;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public class OrderServiceImpl implements IorderService {
@Override
public String getOrder(Integer orderId, String name) {
// 把参数依次装到一个List里面
List<String> argList = new ArrayList();
argList.add(orderId.toString());
argList.add(name);
return SocketUtil.getSocket(url, port, packageName, argList);
}
@Override
public String getOrderName(String name) {
return "订单名称:" + name;
}
}
封装Socket的类
package com.yunhe.client.util;
import java.io.IOException;
import java.net.Socket;
import java.util.List;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public class SocketUtil {
public static String getSocket(String url, int port, String packageName, List<String> argList) {
String reponseData = "";
try {
Socket client = new Socket(url, port);
// 获取服务端的 类 方法 和参数类型
String className = "OrderServiceImpl/r/n";
String method = "getOrderName/r/n";
// 依次写入这四个参数
client.getOutputStream().write(packageName.getBytes());
client.getOutputStream().write(className.getBytes());
client.getOutputStream().write(method.getBytes());
// 遍历方法的参数
for ( String argList1 : argList){
client.getOutputStream().write(argList1.getBytes());
}
client.shutdownOutput();
// 获取服务器返回来的值
byte[] b = new byte[1];
while (client.getInputStream().read(b) != -1) {
reponseData = reponseData + new String(b);
}
} catch (IOException e) {
e.printStackTrace();
}
return reponseData;
}
}
最后的是客户端的main函数
package com.yunhe.client;
import com.yunhe.client.service.impl.OrderServiceImpl;
/**
* class
*
* @author 知识快递
* @date 2018年12月20日
*/
public class ClientBoot {
public static void main(String[] args) {
new OrderServiceImpl().getOrder(1,"Socket");
}
}
现在终于完成了来看成果吧
要先启动服务端