Perfect 网络框架的应用 —— 动态博客开发

发布于: 2016-12-19 10:09
阅读: 1785
评论: 0
喜欢: 34

「Perfect」是一款基于 Swift 的服务端网络框架,并支持在 Linux 系统上部署。

「我的博客」的服务端程序基于Perfect开发,运行在Linux中。

引言

在我的「上一篇文章」中介绍了一下Perfect框架开发的基本方法以及MySQL连接和C++代码接入。在做了一些 Demo 之后便想做个东西出来,于是就做了个博客网站,并且在最近一周做了一次全新的改版。本文就来简单说说做博客过程中的问题。

方案

如果有小伙伴也想用Perfect做个博客的话,我的方案可供参考。关于博客,你有两种选择,动态或静态。

  • 静态托管可以参考「瓜神的博客」(使用了「Jekyll」)和「bs的博客」(使用了「uno-zen」),具体我并不是很了解,在这里提一下。
  • 动态的博客更加好玩一些,可以自由地做数据库、访问统计,IP记录,后台日志,点赞功能等等。由于要开发服务端软件,工作量必然会大一点,另外服务器租用的费用也是一笔成本。

关于服务器方案,我选择的是:阿里云华北区最低配置Ubuntu机器,选择按流量收费,带宽开满(按流量收费带宽选1M和100M的价格是一样的,所以不如开满)。这样的方案包月费用是40元多一点。流量另外算按照0.8元/GB,由于是博客,流量并不会很大,一个月都用不了几块钱。如果将图片资源放在其他地方,一个月连1块钱都用不了。

关于域名,国内机房需要备案,有点麻烦,时间有点久。我由于幕布寄送的问题备案了20天。不过如果购买阿里云的服务器,在阿里云备案,备多少天,备案完会补偿多少天,备案期间的服务器照常可以IP访问。我的备案最终免费送了20天服务器。

当然,既然租了服务器了,也别只给博客用。自己开发的一些小App也可以加上服务端功能啦。如果App是用Swift开发的,那么恭喜你,连模型源代码都可以公用了,赶紧上路吧。

服务端

在我的「上一篇文章」中讲了添加HTTP接口的方法,做网页服务端其实就是把接口返回的内容变成网页源代码罢了。

例如:添加主页URL接口:

extension String {
    static func readFromFile(path: String) -> String {
        let url = URL.init(string: "file://" + "你的网页根目录" + path) ?? URL.init(string: "你的404页面路径")!
        let data = (try? Data.init(contentsOf: url)) ?? Data.init()
        let str = String.init(data: data, encoding: String.Encoding.utf8) ?? ""
        return str
    }
}
    routes.add(uri: "/", handler: { req, res in
        let body = String.readFromFile(path: "index.html")
        res.setBody(string: body)
        res.completed()
    })

网页动态元素的做法直接使用字符串替换即可:

页面中:

    <script>
        var pid = %service_jsvar_post_pid%;
        var page = %service_jsvar_post_in_list_page%;
        var tag = %service_jsvar_post_tag%;
    </script>

服务端中:

extension String {
    func setParam(key: String, value: String) -> String {
        return self.stringByReplacing(string: "%service_\(key)%", withString: value)
    }
}
    var body = String.readFromFile(path: "model/post.html")
    body = body.setParam(key: "jsvar_post_pid", value: "值")
    body = body.setParam(key: "jsvar_post_tag", value: "值")
    body = body.setParam(key: "jsvar_post_in_list_page", value: "值")

这里要特别提两个问题:404入口请求的入口

404入口

Perfect默认的404是一段话,类似于file xxx not found!这样的提示,作为网站的404实在是不合适。添加404并不能像添加接口那样添加,那么404的入口在哪呢?聪明的小伙伴一定会使用全局搜索。直接进这里把那句提示搜出来不就好了。

16010_1

这里搜出来会有两个结果,一个是在PerfectHTTPServer/HTTPServer.swift中的routeRequest方法里,一个在PerfectHTTP/StaticFileHandler.swifthandleRequest方法里。其实一看就知道,在后者中。官方注释道:

// !FIX! need 404.html or some such thing

So,把这个改成自己的404页面就可以了。

请求的入口

如果要做日志统计,那么一定会做记录所有请求的日志。不论什么请求,都会走PerfectHTTPServer/HTTPServer.swift中最下面的routeRequest方法。简单粗暴,直接定义一个闭包,请求进来时调用:

    public var requestCallback: ((HTTPRequest) -> ())?
    private func routeRequest(_ request: HTTPRequest, response: HTTPResponse) {
        requestCallback?(request)
        ......
    }

在初始化服务器时:

    server.requestCallback = { request in
        Log.req(request)
    }
    static func req(_ req: HTTPRequest) {
        let url = req.path                          //请求的url
        let method = req.method                     //方法,GET、Post等
        let host = req.remoteAddress.host           //访问来自哪个IP
        let port = req.remoteAddress.port           //访问来自哪个端口
        let date = "\(Int(Date.init().timeIntervalSince1970 * 1000))"   //时间
        lock.lock()
        server.sql.query("INSERT INTO 你的表 VALUE(......);")
        lock.unlock()
    }

至于点赞什么的功能,也就是一个HTTP请求的事情,点赞直接发个请求给服务端,写入数据库即可。另外一点,如果做数据库记得做缓存。可以是定时刷新缓存或者懒刷新缓存。虽然一个博客并不会有什么性能问题,但是在Dictionary里找数据比用SQL语句在数据库里找方便的多。

前端页面

关于前端我并没有太多发言权,本身就是个渣渣。如果不想自己从头写前端的话可以找找开源的项目,或者看看别人的设计,例如仿照「这里」的设计改编。不过毕竟是自己的东西,还要和服务端协作,用别人的有诸多不便。特别是像我一样前端不熟练的同学,我还是推荐参考别人的设计自己写一个。

结语

从我的博客第一个版本上线以来已经一个多月了,像博客这种小应用,Perfect作为服务端还是很可靠的,没有出过任何问题。但最重要的是,开发方便。对于没有做过后端的 iOS 开发者来说,不妨试试Perfect吧,毫不夸张的说,2小时上手。

目前的博客已经是第二个版本了,刚开始做的满篇 Bug 简直没法看。前端设计参考了「瓜神的博客」,在开发过程中也给了我一些指导,感谢。另外也感谢冰霜大神「halfrost」第一时间把我的博客加入到友情链接里,泪流满面ing。


Thanks for reading.

All the best wishes for you! 💕