• 在 openresty 中使用 capnp lua 库


    1. 安装必要的工具和库

    apt-get install capnproto luarocks
    
    luarocks install lua-capnproto
    luarocks install lua-cjson
    
    • 1
    • 2
    • 3
    • 4

    lua-cjson 库不是必须的,是由于后面的演示程序要使用,就一起装上了。

    可以看下库的安装位置:

    root@350983744ebf:~# luarocks show lua-capnproto
    
    lua-capnproto 0.1.4-5 - Lua-capnproto is a pure lua implementation of capnproto based on LuaJIT.
    
    Lua-capnproto is a pure lua implementation of capnproto based on LuaJIT.
    
    License:        BSD
    Homepage:       https://github.com/calio/lua-capnproto
    Installed in:   /usr/local
    
    Modules:
            capnp (/usr/local/share/lua/5.1/capnp.lua)
            capnp.compile (/usr/local/share/lua/5.1/capnp/compile.lua)
            capnp.util (/usr/local/share/lua/5.1/capnp/util.lua)
            handwritten_capnp (/usr/local/share/lua/5.1/handwritten_capnp.lua)
            handwritten_data_generator (/usr/local/share/lua/5.1/handwritten_data_generator.lua)
            random (/usr/local/share/lua/5.1/random.lua)
            schema_capnp (/usr/local/share/lua/5.1/schema_capnp.lua)
            test (/usr/local/share/lua/5.1/test.lua)
            tool (/usr/local/share/lua/5.1/tool.lua)
    
    Depends on:
            lua ~> 5.1 (using 5.1-1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    默认库都是安装到了 /usr/local/share/lua/5.1/ 目录下。

    2. 编译 capnp 文件

    先将 openresty 自带的 luajit 程序目录加入 PATH 路径中:

    export PATH=$PATH:/usr/local/openresty/luajit/bin
    
    • 1

    新建一个AddressBook.capnp 文件,内容如下:

    @0xdbb9ad1f14bf0b36;  # unique file ID, generated by `capnp id`
    
    struct Person {
      id @0 :UInt32;
      name @1 :Text;
      email @2 :Text;
      phones @3 :List(PhoneNumber);
    
      struct PhoneNumber {
        number @0 :Text;
        type @1 :Type;
    
        enum Type {
          mobile @0;
          home @1;
          work @2;
        }
      }
    
      employment :union {
        unemployed @4 :Void;
        employer @5 :Text;
        school @6 :Text;
        selfEmployed @7 :Void;
        # We assume that a person is only one of these.
      }
    }
    
    struct AddressBook {
      people @0 :List(Person);
    }
    
    
    • 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

    然后编译 capnp 文件:

    root@350983744ebf:~# capnp compile -olua AddressBook.capnp
    root@350983744ebf:~# ls -lh
    total 36K
    -rw-r--r-- 1 root root  532 Oct 22 21:18 AddressBook.capnp
    -rw-r--r-- 1 root root  21K Oct 22 21:20 AddressBook_capnp.lua
    
    • 1
    • 2
    • 3
    • 4
    • 5

    得到 AddressBook_capnp.lua 文件。

    3. 写一个测试程序

    新建一个目录,将 AddressBook_capnp.lua 文件放到这个目录。

    root@350983744ebf:~# mkdir /usr/local/openresty/lua
    root@350983744ebf:~# cd /usr/local/openresty/lua
    root@350983744ebf:/usr/local/openresty/lua# cp /root/AddressBook_capnp.lua .
    
    • 1
    • 2
    • 3

    在这目录新建一个 lua 程序文件 main.lua,内容如下:

    local addressBook = require "AddressBook_capnp"
    local capnp = require "capnp"
    local cjson = require "cjson"
    local util = require "capnp.util"
    
    local data = {
        people = {
            {
                id = 123,
                name = "Alice",
                email = "alice@example.com",
                phones = {
                    {
                        number = "555-1212",
                        ["type"] = "MOBILE",
                    },
                },
                employment = {
                    school = "MIT",
                },
            },
            {
                id = 456,
                name = "Bob",
                email = "bob@example.com",
                phones = {
                    {
                        number = "555-4567",
                        ["type"] = "HOME",
                    },
                    {
                        number = "555-7654",
                        ["type"] = "WORK",
                    },
                },
                employment = {
                    unemployed = "Void",
                },
            },
        }
    }
    
    local bin = addressBook.AddressBook.serialize(data)
    local decoded = addressBook.AddressBook.parse(bin)
    
    ngx.say(cjson.encode(decoded))
    
    • 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

    这个程序将一个 lua 数据【数据格式是按照 AddressBook.capnp 文件定义的】序列化成 capnp 二进制数据,然后将二进制数据反序列化成 lua 数据,最后使用 cjson 库将 lua 数据序列化成 json 格式,使用 nginx 输出。

    4. 验证程序

    修改 nginx 配置文件【 /usr/local/openresty/nginx/conf/nginx.conf】内容为:

    worker_processes  1;
    
    events {
        worker_connections  1024;
    }
    
    http {
        lua_package_path "/usr/local/openresty/lua/?.lua;;";
        
        server {
            listen       80;
            server_name  localhost;
    
            location /capnp {
                content_by_lua_file /usr/local/openresty/lua/main.lua;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    启动 nginx 并验证结果:

    root@350983744ebf:~# /usr/local/openresty/nginx/sbin/nginx        
    
    root@350983744ebf:~# 
    root@350983744ebf:~# curl 127.0.0.1/capnp
    {"people":[{"phones":[{"number":"555-1212","type":"MOBILE"}],"id":123,"name":"Alice","employment":{"school":"MIT"},"email":"alice@example.com"},{"phones":[{"number":"555-4567","type":"HOME"},{"number":"555-7654","type":"WORK"}],"id":456,"name":"Bob","employment":{"unemployed":"Void"},"email":"bob@example.com"}]}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    和预期相符。

  • 相关阅读:
    解决windows下WslRegisterDistribution failed with error: 0x80070050的问题
    《HTTP/2 In Action 中文版本》小结
    .NET 8上进行PDF合并
    Pandas数据分析22——pandas时间序列
    智能合约介绍
    centos7终端无图形界面安装tbb
    mac读写硬盘的软件Tuxera NTFS2023免费版下载
    CHAT 的知识库都有什么?
    【VSCode + Anaconda】VSCode [WinError 126]找不到指定模块
    Bert不完全手册5. 推理提速?训练提速!内存压缩!Albert
  • 原文地址:https://blog.csdn.net/woay2008/article/details/133978273