unity-与skynet通信二三事(sproto,crypt)

Unity 使用 tolua 并与 skynet 通信,rpc 使用 sproto,并接入登陆流程中使用到的 crypt 加密库,修改 tolua 源码加入这两个库

这里只拿 win64 平台 举栗子


skynet 并没有特别推荐使用 sproto,可以换成其他方式,如 json,pbc-lua 等,相对于这两个,sproto 会更方便和高效点,详情看 sproto 说明

相关git链接:


使用 sproto

  1. tolua源码 拿来修改一下,把里面的 sproto 改成新的,新的 sproto 在文件夹 sproto.new 中 ,修改 build_win64.sh
1
2
sproto/sproto.c \
sproto/lsproto.c \

修改为

1
2
sproto.new/sproto.c \
sproto.new/lsproto.c \
  1. 双击 build_win64.sh 即可编译出 dll,路径 E:\tolua_rumtime\Plugins\x86_64\tolua.dll ,然后丢到 unity 中,怎么丢 dll 看官网文档

  2. 增加 dll 导入接口,在 LuaDll.cs 中增加

    1
    2
    [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
    public static extern int luaopen_sproto_core(IntPtr L);
  3. 修改 tolua 相关的 c# 源码,在 LuaClient.cs 脚本中,注册 sproto

    1
    2
    3
    4
    5
    protected virtual void OpenLibs()
    {
    ...
    luaState.OpenLibs(LuaDLL.luaopen_sproto_core);
    }
    • 一般我是不会直接修改这里,在自定义子类中重写这个方法,尽可能少的修改该第三方库,方便以后升级
  4. 然后就可以在lua中测试一下,测试代码参考 tolua 的 ugui 基础框架 里面的代码。


使用 crypt

因为服务端(skynet)使用登陆过程中使用到了 crypt 库,所以直接从 skynet 中提取了 lua-crypt.clsha1.c 两个文件打进去 tolua

  1. 提取 skynet 中 lua-crypt.clsha1.c 两个文件,丢到 tolua_runtime 源码中,修改编译文件 build_win64.sh ,增加

    1
    2
    crypt/lsha1.c \
    crypt/lua-crypt.c \
    • 然后直接编译会报几个 链接 错误,需要修改这两个文件

      1. 修改 lua-crypt.c

        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
        LUALIB_API 
        int luaopen_crypt(lua_State *L) { // 修改0:修改宏 LUAMOD_API(skynet内置) 为 LUALIB_API,函数修改Wie luaopen_crypt,使用是 require "crypt"(就不用加skynet.了)
        //luaL_checkversion(L); // 修改1:skynet 用的是lua5.3,有这个函数,tolua是5.1.4,所以干掉
        static int init = 0;
        if (!init) {
        // Don't need call srandom more than once.
        init = 1 ;
        srand(time(NULL)); // 修改2:srandom 不是标准的c库,所以换成 srand
        }
        luaL_Reg l[] = {
        { "hashkey", lhashkey },
        { "randomkey", lrandomkey },
        { "desencode", ldesencode },
        { "desdecode", ldesdecode },
        { "hexencode", ltohex },
        { "hexdecode", lfromhex },
        { "hmac64", lhmac64 },
        { "hmac64_md5", lhmac64_md5 },
        { "dhexchange", ldhexchange },
        { "dhsecret", ldhsecret },
        { "base64encode", lb64encode },
        { "base64decode", lb64decode },
        { "sha1", lsha1 },
        { "hmac_sha1", lhmac_sha1 },
        { "hmac_hash", lhmac_hash },
        //{ "xor_str", lxor_str }, // 修改3:这个函数用lua5.1里面不存在函数,可能是 skynet 、或者lua53里新增的,干掉
        { NULL, NULL },
        };
        //luaL_newlib(L,l); // 修改4,同样是lua版本问题
        #if LUA_VERSION_NUM < 502
        luaL_register(L, "crypt", l);
        #else
        luaL_newlib(L, l);
        #endif
        return 1;
        }

        这个文件的第二处修改,也是随机数函数,在 lrandomkey 函数中使用到,将 random 修改为 rand ,同样是因为 random 不是c标准库里的东西,参考资料:http://www.itguai.com/c/a4898411.html

      2. 修改 lua-crypt.c ,直接去掉 LUAMOD_API 宏即可

  2. 然后就编译 tolua.dll ,丢到 unity 中替换掉

  3. 在 tolua 的 c# 代码中注册这个库,和 上面 sproto 的 3、4步差不多,增加 dll 导入接口,在 LuaDll.cs 中增加

    1
    2
    [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
    public static extern int luaopen_crypt(IntPtr L);
  4. 修改 tolua 相关的 c# 源码,在 LuaClient.cs 脚本中,注册 crypt

    1
    2
    3
    4
    5
    protected virtual void OpenLibs()
    {
    ...
    luaState.OpenLibs(LuaDLL.luaopen_crypt);
    }
  5. 然后测试一下,如果没有报错就可以使用了

    1
    2
    3
    local crypt = require "crypt"
    local key = crypt.randomkey()
    print(key)
  6. 参考资料:http://www.jianshu.com/p/3c5db3e6b4e7