238 lines
7.6 KiB
Markdown
238 lines
7.6 KiB
Markdown
## 前言
|
||
|
||
因为个人爱好,购买了云服务器,上面部署了静态博客网站,科学上网服务,内网穿透服务。
|
||
|
||
上述条件弄完之后,还剩下很多性能。所以决定自己实现一个服务器应用程序,代码比较简单,也可以说就是练练手。
|
||
|
||
## 访问统计
|
||
|
||
`/api/v1/visit_analysis`
|
||
|
||
`/api/v1/most_viewed_urls`
|
||
|
||
`/api/v1/latest_viewed_urls`
|
||
|
||
表名:visit_analysis
|
||
|
||
| 字段名 | 数据类型 | 约束条件 | 解释 |
|
||
| --------------- | -------- | --------------------- | ---- |
|
||
| id | INTEGER | NOT NULL,PRIMARY KEY | 主键 |
|
||
| url | TEXT | NOT NULL | |
|
||
| visitor_uuid | TEXT | NOT NULL | |
|
||
| last_user_agent | TEXT | NOT NULL | |
|
||
| last_view_time | INTEGER | NOT NULL | |
|
||
| page_view_count | INTEGER | NOT NULL | |
|
||
|
||
1. 创建table visit_analysis。
|
||
2. 插入 url,visitor_uuid,last_user_agent ,last_view_time至表中,如果表中已存在url,visitor_uuid 相同的item,则更新last_user_agent ,last_view_time,并将page_view_count加1,否则创建新的item,并将page_view_count赋值为1。
|
||
3. 根据url 获取 不同的visitor_uuid的个数作为访客数量统计,将所有 page_view_count 累加作为访问次数统计。
|
||
4. 将 url 的 所有 page_view_count 累加,统计出 n 个最大的记录。
|
||
5. 将 url 的 last_view_time进行排序,统计出最新的 n 个记录。
|
||
6. 将所有记录的不同 visitor_uuid 相加作为网站总访客数,将所有page_view_count相加作为网站总访问次数。
|
||
|
||
## 注册/登录
|
||
|
||
```json
|
||
//接口: /api/v1/user/register
|
||
|
||
//POST Body
|
||
{
|
||
"username": "string(6-20位字母数字组合)",
|
||
"password": "string(8-20位,需包含大小写和数字)",
|
||
"email": "string(有效邮箱格式)"
|
||
}
|
||
|
||
// 回复
|
||
{
|
||
"code": 200,
|
||
"message": "注册成功",
|
||
"data": {
|
||
"user_id": 256
|
||
}
|
||
}
|
||
|
||
curl -X POST \
|
||
http://192.168.3.5:8081/api/v1/user/register \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"username": "amass",
|
||
"password": "123456",
|
||
"email": "12345678@qq.com"
|
||
}'
|
||
```
|
||
|
||
|
||
|
||
```json
|
||
//接口: /api/v1/user/login
|
||
|
||
// POST Body
|
||
{
|
||
"username": "string",
|
||
"password": "string",
|
||
}
|
||
|
||
curl -v -X POST \
|
||
http://192.168.3.5:8081/api/v1/user/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"username": "amass",
|
||
"password": "123456",
|
||
"remember_me": true
|
||
}'
|
||
|
||
|
||
{
|
||
"code": 200,
|
||
"message": "login success",
|
||
"data": {
|
||
"user_id": "U123456789"
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
```json
|
||
//接口: /api/v1/user/logout
|
||
|
||
{
|
||
"code": 200,
|
||
"message": "logout success",
|
||
}
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
```json
|
||
//接口: /api/v1/user/verify
|
||
// Cookie: auth=<jwt_token>
|
||
|
||
{
|
||
"code": 200,
|
||
"message": "会话有效",
|
||
"data": {
|
||
"user_id": "U123456789",
|
||
"session_expire": 1669987200
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
一般在Web应用前后端实现中,如何传输账号密码以及保存和后续验证?请给出经典应用方案。
|
||
|
||
用户注册的时候,前端需要把账号密码发送到后端。这里的关键是传输过程的安全,所以必须用HTTPS,不能是明文传输。
|
||
|
||
后端收到密码后,不能直接存明文,得做哈希处理,并且加盐。比如用bcrypt这样的算法,因为它是专门为密码存储设计的,速度慢,可以抵御暴力破解。盐值要每个用户独立生成,这样即使两个用户密码相同,哈希值也不同。
|
||
|
||
然后是登录时的验证。用户输入账号密码后,前端同样通过HTTPS发送到后端。后端根据用户名找到对应的用户记录,取出盐值和哈希后的密码,然后用相同的算法对用户输入的密码进行哈希,比较两者是否一致。如果一致,就生成一个会话或者Token返回给前端,比如JWT。之后的前端请求可以带着这个Token,后端验证Token的有效性来处理后续请求。
|
||
|
||
表名:users
|
||
|
||
| 字段名 | 数据类型 | 约束条件 | 解释 |
|
||
| ------------- | -------- | ----------------------------------- | ----|
|
||
| id | INTEGER | NOT NULL,PRIMARY KEY,AUTO_INCREMENT | 主键 |
|
||
| username | TEXT | UNIQUE,NOT NULL | |
|
||
| password_hash | BLOB | NOT NULL | |
|
||
| salt | BLOB | NOT NULL | |
|
||
| created_at | INTEGER | NOT NULL | |
|
||
|
||
|
||
|
||
## Live2D 模型添加
|
||
|
||
在 XML 配置文件定义`Live2dModelsRoot` 字段,值默认为 `resources/live2d`。
|
||
|
||
模型相关文件放置在 DocumentRoot/resources/live2d下。
|
||
|
||
## Wake On Lan
|
||
|
||
1. 实现一个客户端,上线之后向服务器发送自己的状态,服务器将其作为上下线状态判断。客户端提供了
|
||
2. Web前端可以通过 Http api 获取 上线的客户端提供了哪些 Wake on lan 服务 ,可以显示在页面上。
|
||
3. 当web点击对应的按钮时,服务器通知服务对应的客户端
|
||
4. 客户端接收到指令后,开始向该服务对应的mac进行广播。
|
||
|
||
|
||
## 任务清单
|
||
|
||
| 字段名 | 数据类型 | 约束条件 | 解释 |
|
||
| ------------- | ------------ | --------------------- | ---- |
|
||
| id | INTEGER | NOT NULL,PRIMARY KEY | |
|
||
| create_time | INTEGER | NOT NULL | |
|
||
| parent_id | INTEGER | | |
|
||
| content | VARCHAR(512) | NOT NULL | |
|
||
| finished | BOOL | | |
|
||
| finished_time | INTEGER | | |
|
||
|
||
|
||
|
||
## Core Dump
|
||
|
||
通过命令`ulimit -a`查看:
|
||
|
||
```
|
||
real-time non-blocking time (microseconds, -R) unlimited
|
||
core file size (blocks, -c) 0
|
||
data seg size (kbytes, -d) unlimited
|
||
scheduling priority (-e) 0
|
||
file size (blocks, -f) unlimited
|
||
pending signals (-i) 6846
|
||
max locked memory (kbytes, -l) 228312
|
||
max memory size (kbytes, -m) unlimited
|
||
open files (-n) 65535
|
||
pipe size (512 bytes, -p) 8
|
||
POSIX message queues (bytes, -q) 819200
|
||
real-time priority (-r) 0
|
||
stack size (kbytes, -s) 8192
|
||
cpu time (seconds, -t) unlimited
|
||
max user processes (-u) 6846
|
||
virtual memory (kbytes, -v) unlimited
|
||
file locks (-x) unlimited
|
||
```
|
||
|
||
core file size这一项为0,说明不生成core dump文件。
|
||
|
||
在`/etc/profile`里面加入
|
||
|
||
```
|
||
ulimit -c unlimited
|
||
sysctl -w kernel.core_pattern=core_%t_%s_%d_%e
|
||
```
|
||
|
||
查看帮助`man 5 core`。
|
||
|
||
## 微信公众号对接
|
||
|
||
1. 公众号管理网页:设置与开发→基本配置→服务器配置。
|
||
2. 由于使用的是测试公众号,因此只能够接受消息,微信服务器会将该信息发送至我们的服务器,然后我们可以对该消息进行回复,随后该连接将被关闭。
|
||
|
||
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> Idle
|
||
|
||
Idle --> WaitSetAlarmClock : input 1
|
||
WaitSetAlarmClock --> Idle : process input
|
||
|
||
Idle --> WaitSetText : input 2
|
||
WaitSetText --> Idle : process input
|
||
|
||
Idle --> Idle : not found
|
||
```
|
||
|
||
## 修改历史
|
||
|
||
### 2025/02/28
|
||
|
||
1. 重新新建项目,只存放服务器业务相关代码和文件。
|
||
2. 去除Web Toolkit,以后不再使用它了。
|
||
|
||
### 2021/09/03
|
||
|
||
1. 通过阿里云申请免费SSL证书放置cert目录中。
|
||
2. 修改`conf/nginx.conf`文件,使http全部重定向至https。
|