0
点赞
收藏
分享

微信扫一扫

RPC模式

RPC模式

 

一、概念:

rpc模式:即客户端、服务端之间的信息交流模式,

客户端通过发送请求数据包给服务端,

服务端接收到数据包(拆解数据包),进行业务处理后,返回一个处理过的数据包给客户端,

然后客户端再进行操作。

 

二、流程图

RPC模式_RPC模式

 

三、举例:

❀ 客户端界面(登录界面)

import Client.net.Client;
import Common.entity.BizType;
import Common.entity.User;
import Common.util.SysDto;
/**
* 登录界面类
* @author Huangyujun
*/
public class LoginFrame extends JFrame{//登录客户端
Client client = null;
 //.....界面的东西省略....../**
* 为登录按纽添加事件(~核心功能~~~)
*/
private void loginEvent() {
     //btnLogin: 登录按钮
btnLogin.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//构建客户端
client = new Client("localhost", 8888);
//构建登录业务的DTO(DTO 是数据包对象)
SysDto sysDto = new SysDto(BizType.登录);
          //account和 password 是登录界面的账号和密码输入框
String account = txtLoginName.getText();
String password = txtLoginPwd.getText();
sysDto.setUser(new User(account, password));
//发送
SysDto dto = null;
try {
dto = client.sendAndReadDto(sysDto);
} catch (ClassNotFoundException | IOException e1) {
e1.printStackTrace();
}
//若登录成功后,进入聊天界面
if(dto.getBizType().equals(BizType.登录成功)) {
//打印从服务端处理后的登录用户信息
System.out.println("从服务端处理后的登录用户信息: ");
System.out.println("从服务端返回用户账号:" + dto.getUser().getAccount());
System.out.println("从服务端返回用户密码:" + dto.getUser().getPassword());
}
}
});
}
}

 

❀ 客户端

package Client.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

import Common.entity.BizType;
import Common.util.SysDto;

/**
* 客户端
* @author Huangyujun
*
*/
public class Client {
private String host;
private int port;
private Socket client;
private ObjectOutputStream objOutStream;
private ObjectInputStream objInStream;
private boolean isRunning;

//构造方法
public Client(String host, int port) {
this.host = host;
this.port = port;
isRunning = true;
try {
client = new Socket(host, port);
objOutStream = new ObjectOutputStream(client.getOutputStream());
objInStream = new ObjectInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 发送DTO
* @param sysDto
* @throws IOException
*/
public void sendDto(SysDto sysDto) throws IOException {
objOutStream.writeObject(sysDto);
//推流
objOutStream.flush();
}

/**
* 接收DTO
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
public SysDto readDto() throws ClassNotFoundException, IOException {
Object data = objInStream.readObject();
return (SysDto) data;
}

/**
* 发送并接收DTO
* @param sysDto
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public SysDto sendAndReadDto(SysDto sysDto) throws IOException, ClassNotFoundException {
sendDto(sysDto);
return readDto();
}
/**
* 关闭操作方法
*/
public void close(SysDto sysDto) {
if(sysDto.getBizType().equals(BizType.退出)) {
//发送退出数据包给服务器,让服务器断开处理客户端的客户端任务
try {
sendDto(sysDto);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//退出:关闭各种流和Socket
try {
//休息一下,避免与更新界面冲突
TimeUnit.MILLISECONDS.sleep(5000);
objInStream.close();
objOutStream.close();
client.close();
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Socket getClient() {
return client;
}

public void setClient(Socket client) {
this.client = client;
}

public boolean isRunning() {
return isRunning;
}

public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}

}

 

❀ 数据包

package Common.util;
import java.io.Serializable;
import Common.entity.BizType;
import Common.entity.User;

/**
* 数据传输对象,也需要在网络上传输,实现序列化
* @author Huangyujun
*
*/
public class SysDto implements Serializable {
private static final long serialVersonUID = 2;
private BizType bizType; //数据传输对象类型
//先考虑登录业务所需传输的数据对象
private User user;
//构造方法
public SysDto(BizType bizType) {
this.bizType = bizType;
}

public BizType getBizType() {
return bizType;
}

public void setBizType(BizType bizType) {
this.bizType = bizType;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}
}

 

❀ 服务端

package ServerNet;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import Common.entity.User;
import Common.util.SysDto;

/**
* 服务端
* @author Huangyujun
*
*/
public class Server {
private int port; //端口
private boolean isRunning; //运行状态
private ServerSocket serverSocket; //服务器
/** 客户端任务集合 */
private static List<SocketHandler> listHandler = null;

//构造方法
public Server(int port) {
this.port = port;
isRunning = true;
listHandler = new ArrayList<SocketHandler>();
}

/**
* 启动方法
*/
public void start() {
//构建服务端,并连接
serverSocket = null;
try {
serverSocket = new ServerSocket(port);
System.out.println("服务端已经连接,正在监听端口:" + port);
//循环不断地监听客户端
while(isRunning) {
Socket client = serverSocket.accept();
//创建客户端任务处理客户端业务请求,将当前活跃的客户端传入
SocketHandler socketHandler = new SocketHandler(client);
//listHandler 添加socketHandler 客户端任务
listHandler.add(socketHandler);
//启动客户端任务线程
new Thread(socketHandler).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public ServerSocket getServerSocket() {
return serverSocket;
}

public void setServerSocket(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}

public List<SocketHandler> getListHandler() {
return listHandler;
}
}

 

❀ 客户端处理器

package ServerNet;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import Common.entity.BizType;
import Common.entity.User;
import Common.util.SysDto;
import ServerBiz.ServerBiz;

/**
* 客户端任务类
* @author Huangyujun
*
*/
public class SocketHandler implements Runnable{
private Socket client;
private boolean isRunning;
private ObjectInputStream objInStream;
private ObjectOutputStream objOutStream;
/** 服务端业务处理对象 */
private ServerBiz serverBiz;
//当前用户~登录完成就有啦
private User loginUsers;
//构造方法
public SocketHandler(Socket client) {
     //当前客户端
this.client = client;
serverBiz = new ServerBiz();
isRunning = true;
//获得输入对象流、输出对象流
objInStream = null;
try {
objInStream = new ObjectInputStream(client.getInputStream());
objOutStream = new ObjectOutputStream(client.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void run() {
//先不断地接收客户端传递的业务数据
Object data = null;
try {
while((data = objInStream.readObject()) != null){
//1,先判断数据属于什么业务
if(!(data instanceof SysDto)) {
System.out.println("未知业务类型,无法处理!");
}else {
//2,进行类型转换
SysDto sysDto = (SysDto) data;
//3,调用业务类的方法,处理返回处理后的数据包
SysDto dto = serverBiz.dealWithType(sysDto);
if(dto.getBizType().equals(BizType.登录成功)) {
this.loginUsers = dto.getUser();
}
//4,将处理后得到的数据包写回给客户端
objOutStream.writeObject(dto);
//5,推流
objOutStream.flush();
if(dto.getBizType().equals(BizType.退出成功)) {
//休息10秒钟
Thread.sleep(10000);
//设置客户端任务状态为false,
isRunning = false;
//关闭各种流和Socket
objOutStream.close();
objInStream.close();
client.close();
break;
}
}
}
} catch (ClassNotFoundException | IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
public boolean isRunning() {
return isRunning;
}

public User getLoginUsers() {
return loginUsers;
}
}

 

❀ 服务业务类

package ServerBiz;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import Common.entity.BizType;
import Common.entity.Message;
import Common.entity.User;
import Common.util.SysDto;
import ServerNet.Server;
import ServerNet.SocketHandler;

/**
* 服务端业务处理类,把传进来的Dto进行处理后返回
* @author Huangyujun
*
*/
public class ServerBiz {
//工厂方法
public SysDto dealWithType(SysDto sysDto) throws IOException {
switch(sysDto.getBizType()) {
case 登录:
return doLogin(sysDto);
       case 退出:
return doExit(sysDto);
}
return null;
}
/**
* 登录业务
* @param sysDto
* @return
*/
private SysDto doLogin(SysDto sysDto) {
//1,验证密码、账号是否正确(没有数据库省略)
//2,从数据库获取该用户信息
//3,设置sysDto类型为登录成功
//4,返回设置了用户信息的sysDto
String account = sysDto.getUser().getAccount();
String password = sysDto.getUser().getPassword();
User user = new User(account, password);
System.out.println("当前从客户端传递来的用户账号是:" + account + " 密码是:" + password);
//设置业务类型为登录成功
sysDto.setBizType(BizType.登录成功);
System.out.println("当前在线人数:" +Server.getOnlineHandler().size());
//设置DTO的用户信息
sysDto.setUser(user);
return sysDto;
}

}

 


作者:一乐乐​


举报

相关推荐

0 条评论