frontend/src/component/Admin/Node/Guide/Aria2RPC.js
2021-10-31 09:33:20 +08:00

445 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { lighten, makeStyles } from "@material-ui/core/styles";
import React, { useCallback, useState } from "react";
import Typography from "@material-ui/core/Typography";
import { useDispatch } from "react-redux";
import { toggleSnackbar } from "../../../../actions";
import Link from "@material-ui/core/Link";
import FormControl from "@material-ui/core/FormControl";
import InputLabel from "@material-ui/core/InputLabel";
import Input from "@material-ui/core/Input";
import RadioGroup from "@material-ui/core/RadioGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Radio from "@material-ui/core/Radio";
import Collapse from "@material-ui/core/Collapse";
import Button from "@material-ui/core/Button";
import Alert from "@material-ui/lab/Alert";
import Box from "@material-ui/core/Box";
import FormHelperText from "@material-ui/core/FormHelperText";
import API from "../../../../middleware/Api";
const useStyles = makeStyles((theme) => ({
stepContent: {
padding: "16px 32px 16px 32px",
},
form: {
maxWidth: 400,
marginTop: 20,
},
formContainer: {
[theme.breakpoints.up("md")]: {
padding: "0px 24px 0 24px",
},
},
subStepContainer: {
display: "flex",
marginBottom: 20,
padding: 10,
transition: theme.transitions.create("background-color", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
"&:focus-within": {
backgroundColor: theme.palette.background.default,
},
},
stepNumber: {
width: 20,
height: 20,
backgroundColor: lighten(theme.palette.secondary.light, 0.2),
color: theme.palette.secondary.contrastText,
textAlign: "center",
borderRadius: " 50%",
},
stepNumberContainer: {
marginRight: 10,
},
stepFooter: {
marginTop: 32,
},
button: {
marginRight: theme.spacing(1),
},
viewButtonLabel: { textTransform: "none" },
"@global": {
code: {
color: "rgba(0, 0, 0, 0.87)",
display: "inline-block",
padding: "2px 6px",
fontFamily:
' Consolas, "Liberation Mono", Menlo, Courier, monospace',
borderRadius: "2px",
backgroundColor: "rgba(255,229,100,0.1)",
},
pre: {
margin: "24px 0",
padding: "12px 18px",
overflow: "auto",
direction: "ltr",
borderRadius: "4px",
backgroundColor: "#272c34",
color: "#fff",
fontFamily:
' Consolas, "Liberation Mono", Menlo, Courier, monospace',
},
},
}));
export default function Aria2RPC(props) {
const classes = useStyles();
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const ToggleSnackbar = useCallback(
(vertical, horizontal, msg, color) =>
dispatch(toggleSnackbar(vertical, horizontal, msg, color)),
[dispatch]
);
const testAria2 = () => {
setLoading(true);
API.post("/admin/node/aria2/test", {
type: props.node.Type,
server: props.node.Server,
secret: props.node.SlaveKey,
rpc: props.node.Aria2OptionsSerialized.Server,
token: props.node.Aria2OptionsSerialized.Token,
})
.then((response) => {
ToggleSnackbar(
"top",
"right",
"连接成功Aria2 版本为:" + response.data,
"success"
);
})
.catch((error) => {
ToggleSnackbar("top", "right", error.message, "error");
})
.then(() => {
setLoading(false);
});
};
const mode = props.node.Type === 0 ? "从机" : "主机";
return (
<form
className={classes.stepContent}
onSubmit={(e) => {
e.preventDefault();
props.onSubmit(e);
}}
>
<Alert severity="info" style={{ marginBottom: 10 }}>
<Typography variant="body2">
Cloudreve 的离线下载功能由{" "}
<Link href={"https://aria2.github.io/"} target={"_blank"}>
Aria2
</Link>{" "}
驱动如需使用请在目标节点服务器上以和运行 Cloudreve
相同的用户身份启动 Aria2 并在 Aria2 的配置文件中开启 RPC
服务
<Box component="span" fontWeight="fontWeightBold">
Aria2 需要和{mode} Cloudreve 进程共用相同的文件系统
</Box>{" "}
更多信息及指引请参考文档的{" "}
<Link
href={"https://docs.cloudreve.org/use/aria2"}
target={"_blank"}
>
离线下载
</Link>{" "}
章节
</Typography>
</Alert>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>1</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
{props.node.Type === 0
? "是否需要此节点接管离线下载任务?"
: "是否需要主机接管离线下载任务?"}
<br />
{props.node.Type === 0
? "开启后,用户的离线下载请求可以被分流到此节点处理。"
: "开启后,用户的离线下载请求可以被分流到主机处理。"}
</Typography>
<div className={classes.form}>
<FormControl required component="fieldset">
<RadioGroup
required
value={props.node.Aria2Enabled}
onChange={props.handleTextChange(
"Aria2Enabled"
)}
row
>
<FormControlLabel
value={"true"}
control={<Radio color={"primary"} />}
label="启用"
/>
<FormControlLabel
value={"false"}
control={<Radio color={"primary"} />}
label="关闭"
/>
</RadioGroup>
</FormControl>
</div>
</div>
</div>
<Collapse in={props.node.Aria2Enabled === "true"}>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>2</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
{props.node.Type === 0
? " 在目标节点服务器上与节点 "
: "在与 "}
Cloudreve 进程相同的文件系统环境下启动 Aria2
进程在启动 Aria2 需要在其配置文件中启用 RPC
服务并设定 RPC
Secret以便后续使用以下为一个供参考的配置
</Typography>
<pre>
# 启用 RPC 服务
<br />
enable-rpc=true
<br />
# RPC 监听端口
<br />
rpc-listen-port=6800
<br />
# RPC 授权令牌可自行设定
<br />
rpc-secure={props.node.Aria2OptionsSerialized.Token}
<br />
</pre>
<Alert severity="info" style={{ marginBottom: 10 }}>
<Typography variant="body2">
推荐在日常启动流程中先启动 Aria2再启动节点
Cloudreve这样节点 Cloudreve 可以向 Aria2
订阅事件通知下载状态变更处理更及时当然如果没有这一流程节点
Cloudreve 也会通过轮询追踪任务状态
</Typography>
</Alert>
</div>
</div>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>3</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
在下方填写{mode} Cloudreve Aria2 通信的 RPC
服务地址一般可填写为
<code>http://127.0.0.1:6800/</code>,其中端口号
<code>6800</code>
<code>rpc-listen-port</code>
</Typography>
<div className={classes.form}>
<FormControl fullWidth>
<InputLabel htmlFor="component-helper">
RPC 服务器地址
</InputLabel>
<Input
required
type={"url"}
value={
props.node.Aria2OptionsSerialized.Server
}
onChange={props.handleOptionChange(
"Server"
)}
/>
<FormHelperText id="component-helper-text">
包含端口的完整 RPC
服务器地址例如http://127.0.0.1:6800/,留空表示不启用
Aria2 服务
</FormHelperText>
</FormControl>
</div>
</div>
</div>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>4</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
RPC 授权令牌 Aria2 配置文件中
<code>rpc-secure</code>
</Typography>
<div className={classes.form}>
<Input
value={props.node.Aria2OptionsSerialized.Token}
onChange={props.handleOptionChange("Token")}
/>
</div>
</div>
</div>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>5</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
在下方填写 Aria2 用作临时下载目录的 节点上的
<strong>绝对路径</strong> Cloudreve
进程需要此目录的读执行权限
</Typography>
<div className={classes.form}>
<Input
value={
props.node.Aria2OptionsSerialized.TempPath
}
onChange={props.handleOptionChange("TempPath")}
/>
</div>
</div>
</div>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>5</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
在下方按需要填写一些 Aria2 额外参数信息
</Typography>
<div className={classes.form}>
<FormControl fullWidth>
<InputLabel htmlFor="component-helper">
状态刷新间隔 ()
</InputLabel>
<Input
type={"number"}
inputProps={{
step: 1,
min: 1,
}}
required
value={
props.node.Aria2OptionsSerialized
.Interval
}
onChange={props.handleOptionChange(
"Interval"
)}
/>
<FormHelperText id="component-helper-text">
Cloudreve Aria2 请求刷新任务状态的间隔
</FormHelperText>
</FormControl>
</div>
<div className={classes.form}>
<FormControl fullWidth>
<InputLabel htmlFor="component-helper">
RPC 调用超时 ()
</InputLabel>
<Input
type={"number"}
inputProps={{
step: 1,
min: 1,
}}
required
value={
props.node.Aria2OptionsSerialized
.Timeout
}
onChange={props.handleOptionChange(
"Timeout"
)}
/>
<FormHelperText id="component-helper-text">
调用 RPC 服务时最长等待时间
</FormHelperText>
</FormControl>
</div>
<div className={classes.form}>
<FormControl fullWidth>
<InputLabel htmlFor="component-helper">
全局任务参数
</InputLabel>
<Input
multiline
required
value={
props.node.Aria2OptionsSerialized
.Options
}
onChange={props.handleOptionChange(
"Options"
)}
/>
<FormHelperText id="component-helper-text">
创建下载任务时携带的额外设置参数 JSON
编码后的格式书写您可也可以将这些设置写在
Aria2 配置文件里可用参数请查阅官方文档
</FormHelperText>
</FormControl>
</div>
</div>
</div>
<div className={classes.subStepContainer}>
<div className={classes.stepNumberContainer}>
<div className={classes.stepNumber}>6</div>
</div>
<div className={classes.subStepContent}>
<Typography variant={"body2"}>
完成以上步骤后你可以点击下方的测试按钮测试
{mode}
Cloudreve Aria2 通信是否正常
{props.node.Type === 0 &&
"在进行测试前请先确保您已进行并通过上一页面中的“从机通信测试”。"}
</Typography>
<div className={classes.form}>
<Button
disabled={loading}
variant={"outlined"}
onClick={() => testAria2()}
color={"primary"}
>
测试 Aria2 通信
</Button>
</div>
</div>
</div>
</Collapse>
<div className={classes.stepFooter}>
{props.activeStep !== 0 && (
<Button
color={"default"}
className={classes.button}
onClick={props.onBack}
>
上一步
</Button>
)}
<Button
disabled={loading || props.loading}
type={"submit"}
variant={"contained"}
color={"primary"}
onClick={props.onSubmit}
>
下一步
</Button>
</div>
</form>
);
}