使用纯Java实现一个WebSSH项目的示例代码

2020-03-13 18:02:03王冬梅

第二个分支:如果客户端发来的是操作终端的命令,那么我们就直接转发到终端并且获取终端的执行结果。

具体代码实现:

public void recvHandle(String buffer, WebSocketSession session) {
 ObjectMapper objectMapper = new ObjectMapper();
 WebSSHData webSSHData = null;
 try {
  //转换前端发送的JSON
  webSSHData = objectMapper.readValue(buffer, WebSSHData.class);
 } catch (IOException e) {
  logger.error("Json转换异常");
  logger.error("异常信息:{}", e.getMessage());
  return;
 }
 //获取刚才设置的随机的uuid
 String userId = String.valueOf(session.getAttributes().get(ConstantPool.USER_UUID_KEY));
 if (ConstantPool.WEBSSH_OPERATE_CONNECT.equals(webSSHData.getOperate())) {
  //如果是连接请求
  //找到刚才存储的ssh连接对象
  SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(userId);
  //启动线程异步处理
  WebSSHData finalWebSSHData = webSSHData;
  executorService.execute(new Runnable() {
  @Override
  public void run() {
   try {
   //连接到终端
   connectToSSH(sshConnectInfo, finalWebSSHData, session);
   } catch (JSchException | IOException e) {
   logger.error("webssh连接异常");
   logger.error("异常信息:{}", e.getMessage());
   close(session);
   }
  }
  });
 } else if (ConstantPool.WEBSSH_OPERATE_COMMAND.equals(webSSHData.getOperate())) {
  //如果是发送命令的请求
  String command = webSSHData.getCommand();
  SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(userId);
  if (sshConnectInfo != null) {
  try {
   //发送命令到终端
   transToSSH(sshConnectInfo.getChannel(), command);
  } catch (IOException e) {
   logger.error("webssh连接异常");
   logger.error("异常信息:{}", e.getMessage());
   close(session);
  }
  }
 } else {
  logger.error("不支持的操作");
  close(session);
 }
}

数据通过websocket发送到前端

public void sendMessage(WebSocketSession session, byte[] buffer) throws IOException {
 session.sendMessage(new TextMessage(buffer));
}

关闭连接

public void close(WebSocketSession session) {
 //获取随机生成的uuid
 String userId = String.valueOf(session.getAttributes().get(ConstantPool.USER_UUID_KEY));
 SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(userId);
 if (sshConnectInfo != null) {
  //断开连接
  if (sshConnectInfo.getChannel() != null) sshConnectInfo.getChannel().disconnect();
  //map中移除该ssh连接信息
  sshMap.remove(userId);
 }
}

至此,我们的整个后端实现就结束了,由于篇幅有限,这里将一些操作封装成了方法,就不做过多展示了,重点讲逻辑实现的思路吧。接下来我们将进行前端的实现。

前端实现

前端工作主要分为这么几个步骤:

页面的实现 连接WebSocket并完成数据的接收并回写 数据的发送

所以我们一步一步来实现它。

页面实现

页面的实现很简单,我们只不过需要在一整个屏幕上都显示终端那种大黑屏幕,所以我们并不用写什么样式,只需要创建一个div,之后将terminal实例通过xterm放到这个div中,就可以实现了。