iPad(平板)办公进阶篇

Author: OwnDing

Date: 2025-06-06

2022年的时候写过一篇《告别电脑,完全使用iPad(平板)进行办公、学习、娱乐的最佳方案》

告别电脑,完全使用iPad(平板)进行办公、学习、娱乐的最佳方案 - 知乎

介绍了如何使用iPad进行办公。晃眼已经3年多了,iPad还很新,性能满足我日常所有的使用需求,但是 轻量云服务器 我开始嫌弃它内存不够了(之前新用户优惠买的3年,8G内存)。 最重要的是3年过后的续费费用很高(一年蹲着节日优惠最便宜也要700多续费费用),提升内存配置的价格更高。 这就促使我萌生了使用 更低花费获得更好 使用效果的想法。

本次方案的核心就是把 原先轻量云windows电脑替换成 本地windows电脑。但是由于本地电脑没有公网IP,所以整体的网络方案比较复杂,不适合绝大多数人。不过你也可以直接使用远程软件,比如向日葵todesk、自建远程软件等代替本文所说的网络方案。

直接上图讲解:

image
远程办公可行的网络方案云服务器:采用了 aws 的 最便宜的 512M内存的 lightsail 服务器。在该服务器上搭建了 Headscale 服务端。虽然服务器配置低,用来做网络中转,或其它网络用途绰绰有余。

路由器-openwrt:在家里放置了一台安装 openwrt 操作系统的路由器,这个路由器是在淘宝买的二手。 该路由器需要确保能够安装 tailscale客户端。后续使用时会将该路由器注册到headscale服务器上,并且宣告路由。

电脑:电脑要求接到openwrt的路由器上,同时需要满足低电耗的要求。我买的是 mini主机,16G内存,512G硬盘存储,因特尔N100处理器。这个配置对于日常办公是够用了,价格大概900多。该 主机有“通电自启”功能,不过需要一直插着电源才行,一旦断电就无法自启了,同我想象的通电自启不一样,好在价格便宜,功率比较低(40w~70w),就不强求了。这台电脑我想着至少要用2年,这样每年就不到500块,即使一直开机加上电费也不到700。

image
mini主机iPad或平板:使用之前的平板,不过需要在平板、手机上安装 tailscale 客户端。windows远程桌面也必须。

总之,整体方案就是利用 headscale/tailscale 内网穿透的功能实现 平板 和家里mini主机的远程访问。之所以选用 openwrt的路由器是因为该路由器可以安装tailscale客户端,可以打通平板/手机 同 家里所有网络设备的通讯,在 openwrt宣告 路由比如 192.168.6.0/24 ,mini主机的内网IP是 192.168.6.111,那么你登入 tailscale 客户端后就可以在 iPad / 安卓平板 / 手机 上使用 远程桌面输入 192.168.6.111、账号、密码访问windows了。

image
远程桌面连接/openwrt路由器管理界面本方案需要自行搭建 Headscale服务端,并且需要在 openwrt路由器上安装 tailscale并且宣告路由,整体上还是很复杂的,所以文章不打算写如何安装配置这些服务,只是提供一种场景方案。如果想简单点,直接在 mini主机 上安装诸如向日葵、todesk软件即可,通过这些第三方的软件实现远程连接。

告别电脑,完全使用iPad(平板)进行办公、学习、娱乐的最佳方案

Author: OwnDing

Date: 2022-12-20

今年(2022年)3月份的时候,我使用了3年多的微软 Surface Laptop电池出现鼓包,由于过质保期官方维修费用太贵,自己维修又碰到螺丝拧不动的尴尬场面,因此让我产生了更换电脑的想法。但是心里想了想,7、8千的笔记本电脑只能使用3年时间,平时带着出门重量也大,真心觉得不划算。

此时我想起了,iPad Pro的那句“你的下一台电脑,何必是电脑”的广告词,脑子一热决定不买电脑了,只使用iPad Pro进行办公、学习、娱乐。

我平时使用电脑主要是编写文档、代码开发相关工作。因此我在APP Store上找寻相关的APP替代方案,但是使用下来都不理想,光是一个Word编辑复杂文档都没法完成更不要说是代码编写了。我也在网上参考其他人员使用iPad或平板进行办公的方案,但也存在瑕疵,太贵、不好用!

不过3月底的时候正好看到腾讯轻量云的春节活动,4核、8G内存、10M带宽、100G硬盘,3年只要998元,当即决定采用iPad + 云电脑的方式来实现计划。将云电脑当成一款APP使用。

image
iPad Pro使用RD Client连接云电脑虽然标题是告别电脑,其实只是告别了自己手上的物理电脑,还是需要借助云端电脑完成平时复杂的工作、学习任务。这套方案在实际使用了9个月后,我发现它确实可以完全满足我对办公、娱乐的需求,最重要的是成本低。即使长时间出差(1周左右)也不会出现任何问题,而且平板携带方便。

话不多说,你想只用iPad或平板来进行办公、学习需要准备哪些呢?

** iPad 或 其它平板电脑;蓝牙键盘、鼠标、扩展坞**** 一台云电脑(按需求选择配置,Windows Server 2019操作系统)**是的,只要以上这些物件你就可以摆脱笨重的电脑,同时获得平板电脑的娱乐性。

平板选择

不管是iPad或安卓平板均可以满足办公、学习需求,不过建议平板尺寸尽量选大点。

云服务器选择

可按照自己喜好选择相关云服务器。建议在双11、双12、春节的时候购买轻量云服务器,这些时段优惠大。比如我买的腾讯云轻量服务器3年只要998元(春节优惠),8G内存的配置完全足够应付日常办公。

也可以选择天翼云电脑,带宽比较大,在云电脑看电影也行:

image
天翼云电脑价格如果你购买了3000左右的平板电脑,准备用3年,每年的费用是1000元左右;如果你趁着优惠购买云电脑,每年的费用是600元左右。那么你3年的总费用在4800元,同时拥有了配置还行的电脑以及平板,是不是感觉很赚?

安全建议(重点)

iPad 或 其它平板通过微软 RD Client连接到云电脑,由于远程控制端口暴露在外网,不可避免的带来网络安全问题。可以参照以下建议来加强云电脑的安全:

1、采用强密码。请为云服务器设置强密码。

2、多因子认证。安装 Duo Security免费版,远端登入云电脑时需要手机确认。网站地址:Multi-Factor Authentication & Single Sign-On

image
远端登入时需要手机二次验证
image
Duo Security设置的远端登入认证
image
登入时通过手机Duo授权认证3、安装IPBan(免费)。由于远端连接的相关端口暴露在互联网会导致别人暴力破解,安装IPBan后,可以将多次登入失败的IP地址自动加入防火墙禁用。网址:GitHub - DigitalRuby/IPBan: Since 2011, IPBan is the worlds most trusted, free security software to block hackers and botnets. With both Windows and Linux support, IPBan has your dedicated or cloud server protected. Upgrade to IPBan Pro today and get a discount. Learn more at ↓

image
IPBan的Github主页以上三个都是基础的安全建议,不过有这3个基本上不会出现云电脑被被人登入的情况。

其它的安全建议比如更改远端的端口、限制固定IP登入云电脑等等,对大多数人来说有些困难。

搭建在线编程环境(适合程序开发人员)

对于开发人员或正在学习开发的人员,拥有自己的服务器可以搭建在线编程环境,使用iPad或平板的浏览器进行编程、调试。

1、前端,安装Code-Server(免费)

image
在线编程、调试2、后端,安装 JetBrains Projector(免费)

image
IDEA 在线编程、调试如果相关端口暴露在公网上,需要格外重视安全问题。 不建议公开端口。

总结

现阶段来说,iPad或其它安卓平板的APP是不能满足大多数人办公需求的,但是搭配上云电脑后就不同了,此时你真的可以抛弃你身边的电脑,不管是出门、出差都可以只带一台平板电脑。临时应急的话,你也可以通过手机登入云电脑处理下一些紧急事务。

image
手机版 RD Client,临时应急使用对于有移动办公需求的人来说,这套方案无可挑剔 ;)

构建OpenVPN集群,实现端到端安全互联

Author: OwnDing

Date: 2021-09-04

问题

最近在帮一家子公司处理一些IoT相关的事情,碰到一个需求:要让公司的5G网关产品能够安全的连接到服务器,并且同一个客户公司帐下的5G网关能够相互联通访问

能够满足成千上万的客户端的安全连接各个客户端之间能够相互联通访问原有的5G网关产品自带有OpenVPN功能可以安全的连接到服务器,也可以在一个OpenVPN服务器内相互联通。但是,一台OpenVPN服务器能提供的VPN不超过200个,Windows客户端的话只有60多个,那么如何满足成千上万个5G网关产品连接呢?

面对这一问题,自然而然的想到了搭建OpenVPN集群,一个OpenVPN服务器提供100个连接,那么100台服务器自然就可以提供1万个连接了。不过随之新的问题又来了。我们需要同一个公司帐下的5G网关产品能够相互联通。一个公司有20台5G网关,10台连接到A服务器上了,10台连接到B服务器上了,那么这20台网关如何相互联通访问呢?

基本思路

搭建一个OpenVPN集群,集群在同一个子网内集群内的OpenVPN使用相同的密钥证书当OpenVPN客户端连接到服务器后,集群内其它服务器添加一条路由,将客户端IP路由到相关连接的服务器上

测试

image
OpenVPN测试示意图说明:两台OpenVPN服务器使用docker部署在一台阿里云服务器上,并且共享密钥证书。左边的客户端连接到VPN服务器(172.17.0.2,该地址为docker容器地址),获取到虚拟地址 192.168.255.6;右边的客户端连接到VPN服务器(172.17.0.4,该地址为docker容器地址),获取到虚拟地址 192.168.255.10。

1、客户端各自连接到对应的服务器上

2、在OpenVPN服务器上添加一条路由

1
route add -host 192.168.255.6 gw 172.17.0.2

3、在 192.168.255.10 客户端上 ping 另一个客户端

1
ping 192.168.255.6

4、可看到两个客户端可ping通

进阶

上面的测试例子使用的是同一网段的虚拟地址,一个网段能够提供的IP很有限无法满足需求,同时路由需要自己手动添加比较麻烦。我们需要不同OpenVPN服务器提供不同网段的虚拟地址,而且服务器能够自动添加相关路由。针对这一需求,在Github上找到一个示例。

部署OpenVPN集群,各个服务器使用相同的密钥证书,但是配置文件中的server网段可不同使用OpenVPN的learn-address脚本,当服务器接收到连接(add、update、delete)时,自动把连接信息进行子网内广播其它服务器接收到广播后自动添加或删除路由资料:

OpenVPN Cluster

海康摄像机/录像机对接方式记录

Author: OwnDing

Date: 2025-01-02

最近有在做海康摄像机/录像机对接方面的工作,之前也做过类似的工作,但都比较定制化,这次趁着自己有些空做些对接实践。

本次对接海康摄像头/录像机是使用IP直接读取摄像头的数据,并没有用到海康的平台。

本次测试的对接方式有2种:

1)使用海康的SDK进行对接,需要登入到海康官网下载对应的SDK。

2)使用ZLMediaKit 直接拉取摄像头的 rtsp流,然后进行转换后,使用其它软件可以直接播视频监控。

总体来说,第二种方案简单快速无需自己编程。

1、SDK对接

SDK对接,需要自己进行程序编写。此处给出一个Spring Boot程序集成海康SDK的例子。

代码Demo链接:

https://github.com/OwnDing/hkdemo.git

2、ZLMediaKit中转读取

此种方法比较简单,无需自己编写代码即可提供可供VLC软件或前端播放的监控视频。

建议使用Docker进行部署ZLMediaKit。

1)确定摄像头rtsp地址

使用浏览器访问摄像头的控制台,比如摄像头的IP是192.168.88.88,那么在浏览器中输入:http://192.168.88.88 即可访问摄像头的控制台,输入账号密码即可登入。

确定好rtsp的端口:

image
端口查看rtsp流地址示例:

规则:rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream

实例:rtsp://admin:hik12345@192.168.88.88:554/h266/ch1/main/av_stream

说明:

username: 用户名。例如admin。

password: 密码。例如12345。

ip: 为设备IP。

port: 端口号默认为554。

codec:有h264、MPEG-4、mpeg、h266这几种。

channel: 通道号,起始为1。

subtype: 码流类型,主码流为main,辅码流为sub。

例如,请求海康摄像机通道1的主码流,Url如下

主码流:rtsp://admin:12345@192.0.0.64:554/h264/ch1/main/av_stream

你可以下载一个VLC播放器,然后把rtsp地址复制到VLC播放器里进行播放测试(菜单:媒体–>流–>网络),能正常播放说明地址正确。

image

2)部署ZLMediaKit

使用Docker进行部署:

docker run -id -p 1935:1935 -p 8080:80 -p 8443:443 -p 8554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp -p 9000:9000/udp zlmediakit/zlmediakit:master

ZLMediaKit 启动后,配置文件在容器中 /opt/media/conf/config.ini (这是容器中的文件), 里面有 secret 密钥。我们访问ZLMediaKit控制台需要这个密钥。

3)访问ZLMediaKit控制台。

访问ZlMediaKit控制台,访问形式需要带上密钥:

http://192.168.88.10:8080/webassist/?secret=p7ApNF5w0AmnPHConD7NKV4TBrNnKyow

其中secret在容器中config.ini文件中。

image
ZLMediaKit控制台4)添加rtsp流

添加rtsp流有两种方法:

第一种:此处可以在ZLMediaKit的控制台操作完成,点击”拉流代理”

image
拉流代理第二种:使用API工具

image
API添加代理使用GET方法,访问ZLMediaKit所在服务器/电脑的 IP:PORT/index/api/addStreamProxy

填入:secret、url、stream、app、vhost 5个参数。

secret:zlmediakit的secret

url:是摄像头rtsp流地址

stream:可自行填写

app:可填 live

vhost:填 ZLMediaKit所在服务器/电脑的 IP

当返回如上图数据时即表示成功,在ZLMediaKit控制台”拉流代理”菜单中可以看到我们刚添加的代理。

使用API生成的URL,注意需要加上端口,因为容器部署后端口有映射。

使用VLC打开 流:http://192.168.83.10:8080/live/zt/hls.m3u8 即可看到监控视频

其中 http://192.168.83.10:8080/live/zt 是返回的数据加上端口,然后 hls.m3u8 是固定的路径。

如果你不想使用VLC打开 http://192.168.83.10:8080/live/zt/hls.m3u8 可以自己创建一个 html 页面,然后使用浏览器打开这个 html 即可看到监控视频。

html示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html>
<head>
<title>[HLS](https://zhida.zhihu.com/search?content_id=252193051&content_type=Article&match_order=1&q=HLS&zhida_source=entity) Stream Player</title>
</head>
<body>
<h1>Live Stream</h1>
<video id="video" controls autoplay></video>
<script src="https://cdn.jsdelivr.net/hls.js/latest/hls.min.js"></script>
<!-- <script src="./dist/hls.js.d.ts"></script> -->
<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('http://192.168.83.10:8080/live/zt/hls.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// 如果浏览器原生支持 HLS,则直接设置 video.src
video.src = 'http://192.168.83.10:8080/live/zt/hls.fmp4.m3u8';
video.addEventListener('loadedmetadata',function() {
video.play();
});
}
</script>
</body>
</html>

3、异常问题记录

1)使用VLC能够打开 http://192.168.83.10:8080/live/zt/hls.m3u8 链接,但是使用浏览器一直无法播放HLS

问题原因:摄像头的编码格式是 H.265

解决方法:在摄像头控制台将编码格式改成 H.264

image
视频编码

4、家用视频方案

现在市面上有很多家用摄像头,用户可以在家里安装摄像头,然后通过厂商的APP实时查看摄像头内容。但是市面上的方案都有一个问题,就是摄像头的资料会存储到厂商的服务器里,并且需要每年付费使用。摄像头内容比较隐私,我不想将内容直接存储在厂家那,最重要的是每年还需要付费使用云资源。

我自己长期有一台云服务器,我就在想是不是可以将视频内容直接存到我云服务器上,这样我也可以实时查看摄像头的内容。

实际上使用ZLMediaKit可以自己搭建视频监控平台,将数据存储到自己的云服务器或者百度网盘之类的工具上。

在 Tailscale 的 4via6 功能中,IPv4 地址会被映射到一个特定的 IPv6 子网中。现有信息如下:

  • IPv6 子网fd7a:115c:a1e0:b1a:0:7:c0a8:600/120
  • 对应的 IPv4 子网192.168.6.0/24

192.168.6.0/24 是 openwrt 路由器的 IPv4 地址。fd7a:115c:a1e0:b1a:0:7:c0a8:600/120 是 Tailscale 分配给 openwrt 的 IPv6 地址。

📌 问题

现在有一个 IPv4 地址 192.168.6.146,如何计算出其对应的 IPv6 地址?

📌 IPv6 和 IPv4 的映射规则

Tailscale 的 4via6 功能通常会将 IPv4 地址嵌入到 IPv6 地址中,具体方式如下:

  1. IPv4 地址的结构192.168.6.x

    • 192.168.6 是 IPv4 的前三个字节,对应 IPv6 地址中的 c0a8:06(即 192.168.6 的十六进制表示)。
    • x 是 IPv4 的最后一个字节,对应 IPv6 地址的最后 8 位。
  2. IPv6 子网结构fd7a:115c:a1e0:b1a:0:7:c0a8:600/120

    • 前 120 位(15 字节)是固定的。
    • 最后 8 位(1 字节)是可变的,用于表示 IPv4 的最后一个字节。

🔍 如何计算 IPv4 对应的 IPv6 地址

192.168.6.146 为例:

  1. IPv4 最后一个字节146

    • 转换为十六进制:146 = 0x92
  2. IPv6 地址的最后 8 位0x92

  3. 完整 IPv6 地址

    • 0x92 替换到 IPv6 子网的最后 8 位中。
    • 原始 IPv6 子网的最后部分是 600,因此最终 IPv6 地址为:
      1
      fd7a:115c:a1e0:b1a:0:7:c0a8:692

✅ 最终答案

IPv4 地址 IPv6 地址
192.168.6.146 fd7a:115c:a1e0:b1a:0:7:c0a8:692

📌 附注

  • IPv6 地址格式:每个段由 4 位十六进制数表示,允许省略前导零。
  • 子网掩码/120 表示前 120 位固定,最后 8 位用于 IPv4 地址的映射。
  • 验证方法:你可以使用 ping6traceroute6 测试该 IPv6 地址是否能访问对应的 IPv4 设备。

🧠 总结

Tailscale 的 4via6 功能通过将 IPv4 地址的最后一个字节映射到 IPv6 地址的最后 8 位,实现了 IPv4 和 IPv6 的双向通信。对于 192.168.6.146,其对应的 IPv6 地址为:

1
fd7a:115c:a1e0:b1a:0:7:c0a8:692

为了在国内方便使用OpenAI及Google Gemini的API,我们可以使用海外服务器代理OpenAI及Google的相关API。
服务器可使用便宜的AWS轻量服务器,每月3.5美元左右。
下面是整个Nginx的配置文件,修改SSL证书地址即可使用。以下Nginx配置,我已经稳定使用了半年多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
user  root;
worker_processes auto;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/nginx-access.log;
error_log /var/log/nginx/nginx-error.log;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';


sendfile on;

keepalive_timeout 65;

gzip on;
gzip_static on;

proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;

fastcgi_buffers 8 128k;
send_timeout 60;

server {
listen 443 ssl;
server_name azure.ownding.xyz;
ssl_certificate /home/chatgpt/cert/azure.ownding.xyz_bundle.crt;
ssl_certificate_key /home/chatgpt/cert/azure.ownding.xyz.key;
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
location / {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept,Authorization';
#支持put和delete请求
return 200;
}
# # 设置是否允许 cookie 传输
# add_header Access-Control-Allow-Credentials true;
# # 允许请求地址跨域 * 做为通配符
# add_header Access-Control-Allow-Origin *;
# add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,PATCH,OPTIONS';
# add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept,Authorization';
proxy_pass https://api.openai.com/;
proxy_ssl_server_name on;
proxy_set_header Host api.openai.com;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

server {
listen 8080 ssl;
server_name generativelanguage.googleapis.com;
ssl_certificate /home/chatgpt/cert/azure.ownding.xyz_bundle.crt;
ssl_certificate_key /home/chatgpt/cert/azure.ownding.xyz.key;
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

proxy_http_version 1.1;
proxy_set_header Host generativelanguage.googleapis.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location / {
proxy_pass https://generativelanguage.googleapis.com;
proxy_ssl_server_name on;
}
}
}

如果项目中、或者个人网盘需要使用到Office文件的在线预览和编辑功能,并且想免费获得,那么有以下两种效果较好的方案。

  • 使用OnlyOffice社区版。可在线预览、编辑、实时协作。
  • 使用微软Office Online Server。部署软件可在MSDN i tell you 网站下载。

异常报错:Caused by: org.flowable.common.engine.api.FlowableWrongDbException: version mismatch: library version is '6.7.1.0', db version is 5.99.0.0
原因:

  • 数据库缺少相关表和数据,导入flowable相关表即可。版本数据存在 act_ge_prperty
  • 数据库没有设置不区分大小写,设置 lower_case_table_names=1
  • 使用的mycat 1.6.7.4 版本,升级到 1.6.7.6 版本可避免

现在市面上有很多文档存储管理的云服务,比如坚果云。这些服务除了提供文件存储之外,高级功能都提供文件内容的搜索服务。
那么文件内容搜索有什么用呢?当我们需要查找文件时,一般都是查找文件名,但是很多时候我们不太记得文件名,只记得几个关键字词,需要根据这些关键字词查找到对应的文档。
如果自行开发文档全文搜索程序,简单的思路如下:

  • 对于标准文档内容,比如PDF(非扫描版)、微软 Office、TXT等等,可直接使用 Apache Tika 读取文件的内容。
  • 对于非标准的文档内容,比如扫描档PDF、图片等可使用OCR工具识别出文件里的内容。将PDF转换成图片,然后使用PaddleOCR识别
  • 对于读取到的文本内容,存储到 Elasticsearch
  • 从ES中查找关键字信息即可。

在AWS上购买了一台1v,512M配置的lightsail,除了用作网络跳转之外平时都是100%空闲。如果不好好利用起来,感觉每月$3.5的花费挺不值。因此就打算部署一套博客,平时也一直有使用Onenote记笔记的习惯,就打算让这个博客当作补充,毕竟不出意外,这台低配VPN会一直续租下去。
对于搭建博客起先想到的是Wordpress,也成功部署了,但是由于这台服务器的配置实在太低而且MySQL部署在腾讯云上,每次点击都需等上好几秒,遂放弃使用Wordpress。
鉴于该台服务器的配置,决定只用来部署静态网站,后面确定选用Hexo

系统配置

  • 操作系统:Ubuntu20.04
  • 资源:1核、512M内存、20G硬盘

安装Node

  • 安装Node 16,如果安装其它版本,请将 setup_16.x 中的 16 改成对应的大版本号即可,比如 15、14等 \
    1
    curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
    1
    sudo apt-get install -y nodejs
  • 检查Node及npm版本,正确安装后会有版本号输出
    1
    2
    node --version
    npm --version

安装Hexo

  • 安装hexo-cli
    1
    npm install hexo-cli -g

创建项目

  • 创建一个 hexo 项目,命名为 blog
    1
    cd /srv
    1
    hexo init blog
    1
    cd blog

部署项目

  • 生产网站的静态文件

    1
    hexo g

    此时,blog 目录下会生产一个 public 目录,里面就是网站需要的文件

  • 安装 nginx ,并且修改 nginx.conf 文件,在 etc/nginx 目录下可找到。添加下面配置。

    1
    2
    3
    4
    5
    6
    7
    8
    server {
    listen 80;
    server_name blogServer;
    autoindex_localtime on;
    client_max_body_size 1200M;
    root /srv/blog/public;
    index index.html;
    }

    其中 server 中的 root 需要指向生产的 public 目录

  • 启动 nginx 后即可访问你的博客

新增文章

-

1
2
cd /srv/blog
hexo new "你文章的标题"

此时在 source/_posts 目录下会生成相应的 .md 文件

删除文章

  • 直接删除 source/_posts 中的文章文件
  • 程序生成静态文件
    1
    hexo g
    即可更新网站
0%