{ "version": "https://jsonfeed.org/version/1", "title": "Lua", "description": "Lua is a powerful, fast, lightweight, embeddable scripting language.", "home_page_url": "go/lua", "feed_url": "feed/lua.json", "icon": "https://cdn.v2ex.com/navatar/8d5e/957f/147_large.png?m=1586483655", "favicon": "https://cdn.v2ex.com/navatar/8d5e/957f/147_normal.png?m=1586483655", "items": [ { "author": { "url": "member/riseworlds", "name": "riseworlds", "avatar": "https://cdn.v2ex.com/gravatar/cfe06a9a7ff045e6034987f4577419d6?s=73&d=retro" }, "url": "t/1131968", "title": "\u4f7f\u7528 Android Lua Helper \u5728 VSCODE \u4e2d\u8c03\u8bd5\u5b89\u5353 Lua \u5e94\u7528", "id": "t/1131968", "date_published": "2025-05-15T06:32:46+00:00", "content_html": "

\u4e00\u3001VSCODE \u4e0e Android Lua Helper \u7684\u529f\u80fd\u7279\u70b9

\n

Visual Studio Code\uff08 VSCODE \uff09\u662f\u4e00\u6b3e\u529f\u80fd\u5f3a\u5927\u7684\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5b83\u4ee5\u5176\u9ad8\u5ea6\u53ef\u5b9a\u5236\u7684\u754c\u9762\u3001\u5f3a\u5927\u7684\u6269\u5c55\u751f\u6001\u7cfb\u7edf\u3001\u6d41\u7545\u7684\u6027\u80fd\u8868\u73b0\u4ee5\u53ca\u5bf9\u4f17\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u5929\u7136\u652f\u6301\u800c\u5907\u53d7\u5f00\u53d1\u8005\u9752\u7750\u3002\u5728\u4f17\u591a\u7684\u5f00\u53d1\u573a\u666f\u4e2d\uff0cVSCODE \u90fd\u5c55\u73b0\u51fa\u4e86\u5353\u8d8a\u7684\u6027\u80fd\u548c\u7075\u6d3b\u6027\u3002\nLua \u4f5c\u4e3a\u4e00\u79cd\u8f7b\u91cf\u7ea7\u7684\u811a\u672c\u8bed\u8a00\uff0c\u5728\u6e38\u620f\u5f00\u53d1\u3001\u79fb\u52a8\u5e94\u7528\u5f00\u53d1\u7b49\u9886\u57df\u6709\u7740\u5e7f\u6cdb\u7684\u5e94\u7528\u3002\u7136\u800c\uff0c\u7531\u4e8e Lua \u662f\u4e00\u95e8\u5c0f\u4f17\u8bed\u8a00\uff0c\u76f8\u5173\u7684\u5f00\u53d1\u5de5\u5177\u5e76\u4e0d\u50cf\u4e3b\u6d41\u8bed\u8a00\u90a3\u6837\u5b8c\u5584\u3002Android Lua Helper \u63d2\u4ef6\u7684\u51fa\u73b0\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u4e00\u7cfb\u5217\u5f3a\u5927\u7684\u529f\u80fd\uff0c\u6781\u5927\u5730\u63d0\u9ad8\u4e86 Lua \u4ee3\u7801\u7684\u5f00\u53d1\u6548\u7387\u548c\u8d28\u91cf\u3002\nAndroid Lua Helper \u63d2\u4ef6\u5177\u6709\u591a\u79cd\u529f\u80fd\uff0c\u5982\u7b26\u53f7\u5b9a\u4e49\u8df3\u8f6c\u3001\u4ee3\u7801\u683c\u5f0f\u5316\u3001\u7b26\u53f7\u67e5\u627e\u3001\u5168\u5c40\u5f15\u7528\u67e5\u627e\u4ee5\u53ca\u667a\u80fd\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9519\u8bef\u68c0\u6d4b\u3001Lua \u4ee3\u7801\u7247\u6bb5\u63d0\u793a\u7b49\u3002\u8fd9\u4e9b\u529f\u80fd\u4f7f\u5f97\u5f00\u53d1\u8005\u5728\u7f16\u5199 Lua \u4ee3\u7801\u65f6\u66f4\u52a0\u9ad8\u6548\u548c\u51c6\u786e\u3002\u4f8b\u5982\uff0c\u4ee3\u7801\u8865\u5168\u529f\u80fd\u53ef\u4ee5\u5927\u5927\u51cf\u5c11\u5f00\u53d1\u8005\u7684\u8f93\u5165\u65f6\u95f4\uff0c\u63d0\u9ad8\u5f00\u53d1\u901f\u5ea6\uff1b\u8bed\u6cd5\u9519\u8bef\u68c0\u6d4b\u529f\u80fd\u53ef\u4ee5\u5e2e\u52a9\u5f00\u53d1\u8005\u53ca\u65f6\u53d1\u73b0\u5e76\u4fee\u590d\u4ee3\u7801\u4e2d\u7684\u9519\u8bef\uff0c\u907f\u514d\u5728\u8fd0\u884c\u65f6\u51fa\u73b0\u95ee\u9898\u3002Android Lua Helper\u63d2\u4ef6\u8fd8\u62e5\u6709\u4f4e\u5185\u5b58\u6d88\u8017\u548c\u9ad8\u5b9e\u65f6\u6027\u7684\u4f18\u70b9\uff0c\u5373\u4fbf\u9762\u5bf9\u89c4\u6a21\u5e9e\u5927\u7684\u9879\u76ee\uff0c\u4e5f\u80fd\u6d41\u7545\u8fd0\u884c\uff0c\u6beb\u65e0\u5361\u987f\u4e4b\u611f\u3002\n\u6b64\u5916\uff0cAndroid Lua Helper \u63d2\u4ef6\u8fd8\u652f\u6301\u591a\u79cd Lua \u7248\u672c\uff0c\u5982 Lua 5.1 \u548c Lua 5.3\uff0c\u6ee1\u8db3\u4e86\u4e0d\u540c\u9879\u76ee\u7684\u9700\u6c42\u3002\u63d2\u4ef6\u7684\u4e0d\u65ad\u66f4\u65b0\u548c\u6539\u8fdb\u4e5f\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u5f00\u53d1\u4f53\u9a8c\u3002Android Lua Helper \u652f\u6301\u4f7f\u7528\u5b89\u5353 ADB \u5de5\u5177\u8fde\u63a5\u624b\u673a\uff0c\u5b9e\u73b0\u8fdc\u7a0b\u8c03\u8bd5\uff0c\u5b89\u88c5\u5378\u8f7d\u5e94\u7528\uff0c\u622a\u5c4f\u5230\u672c\u5730\uff0c\u542f\u52a8scrcpy\u7b49\u3002\n\u603b\u4e4b\uff0cVSCODE \u4e0e Android Lua Helper \u7684\u7ed3\u5408\u4e3a Android \u5f00\u53d1\u4e2d\u7684 Lua \u8bed\u8a00\u9879\u76ee\u63d0\u4f9b\u4e86\u5f3a\u5927\u7684\u652f\u6301\uff0c\u4f7f\u5f97\u5f00\u53d1\u8005\u80fd\u591f\u66f4\u52a0\u9ad8\u6548\u5730\u8fdb\u884c\u5f00\u53d1\u5de5\u4f5c\u3002

\n

\u4e8c\u3001VSCODE \u4e0e Android Lua Helper \u7684\u96c6\u6210

\n

\u9996\u5148\uff0c\u6211\u4eec\u9700\u8981\u5b89\u88c5 VSCODE\uff0c\u7136\u540e\u5b89\u88c5 Android Lua Helper \u63d2\u4ef6\u3002\n\u70b9\u51fb\u6b64\u94fe\u63a5\u76f4\u63a5\u5728VSCODE\u4e2d\u5b89\u88c5\uff0c\u6216\u5728 VSCODE \u7684\u8f6f\u4ef6\u5546\u5e97\u5b89\u88c5 Android Lua Helper \u63d2\u4ef6\u6781\u4e3a\u7b80\u4fbf\u3002\u9996\u5148\u6253\u5f00 VSCODE\uff0c\u76ee\u5149\u805a\u7126\u4e8e\u4fa7\u8fb9\u680f\u5e95\u90e8\uff0c\u90a3\u91cc\u6709\u4e00\u4e2a\u6269\u5c55\u5546\u5e97\u5165\u53e3\u56fe\u6807\uff0c\u5f62\u4f3c\u65b9\u5757\u3002\u8f7b\u8f7b\u70b9\u51fb\u6b64\u56fe\u6807\uff0c\u4fbf\u4f1a\u5f00\u542f\u4e00\u4e2a\u5168\u65b0\u89c6\u56fe\uff0c\u5176\u4e2d\u7f57\u5217\u7740\u4f17\u591a\u63d2\u4ef6\u3002\u63a5\u7740\uff0c\u5728\u641c\u7d22\u680f\u4e2d\u8f93\u5165 Android Lua Helper \u5e76\u6309\u4e0b\u56de\u8f66\u952e\u3002\u968f\u540e\uff0c\u5728\u641c\u7d22\u7ed3\u679c\u91cc\u627e\u5230 Android Lua Helper \u63d2\u4ef6\uff0c\u70b9\u51fb \u201c\u5b89\u88c5\u201d \u6309\u94ae\u3002\u5f85\u5b89\u88c5\u5b8c\u6210\uff0c\u518d\u70b9\u51fb \u201c\u91cd\u65b0\u52a0\u8f7d\u201d \u6309\u94ae\u4ee5\u542f\u7528\u8be5\u63d2\u4ef6\u3002\n\u63d2\u4ef6\u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u6211\u4eec\u9700\u8981\u914d\u7f6e VSCODE\uff0c\u4ee5\u652f\u6301 Android Lua Helper \u7684\u8c03\u8bd5\u3002

\n

\u4e09\u3001\u8c03\u8bd5\u914d\u7f6e\u5168\u6d41\u7a0b

\n

\uff08\u4e00\uff09\u521b\u5efa launch.json \u6587\u4ef6

\n

\u5728\u5b89\u88c5\u597d Android Lua Helper \u63d2\u4ef6\u540e\uff0c\u70b9\u51fb\u8fd0\u884c\u6309\u94ae\uff0c\u63a5\u7740\u70b9\u51fb\u521b\u5efa launch.json\uff0c\u9009\u62e9\u8c03\u8bd5\u5668\u65f6\uff0c\u6211\u4eec\u8981\u9009\u62e9 AndroidLuaHelper\uff1aDebug\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5c31\u50cf\u662f\u4e3a\u6211\u4eec\u7684\u8c03\u8bd5\u4e4b\u65c5\u642d\u5efa\u8d77\u4e86\u4e00\u5ea7\u6865\u6881\u3002\u5b83\u4e3a\u540e\u7eed\u7684\u8c03\u8bd5\u5de5\u4f5c\u63d0\u4f9b\u4e86\u57fa\u7840\u7684\u914d\u7f6e\u6846\u67b6\uff0c\u786e\u4fdd\u6211\u4eec\u80fd\u591f\u987a\u5229\u5730\u8fdb\u884c Lua \u4ee3\u7801\u7684\u8c03\u8bd5\u3002 \"1\"\n\u5728 launch.json \u6587\u4ef6\u4e2d\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u5982\u4e0b\u5185\u5bb9\uff1a\"4\"

\n\n

\uff08\u4e8c\uff09\u6dfb\u52a0LuaPanda.lua\u6587\u4ef6\u5230\u9879\u76ee\u4e2d

\n

\u6309\u5feb\u6377\u952eCtrl+Shift+P\uff0c\u8f93\u5165AndroidLuaHelper\uff1aCopy Debug file\uff0c\u518d\u6309\u56de\u8f66\u952e\u3002\n\u9009\u62e9\u5408\u9002\u7684\u9879\u76ee\u76ee\u5f55\u540eLuaPanda.lua\u6587\u4ef6\u4f1a\u81ea\u52a8\u590d\u5236\u5230\u76ee\u5f55\u4e0b\uff0c\u5e76\u547d\u540d\u4e3a LuaPanda.lua\u3002\n\"2\"

\n

\uff08\u4e09\uff09\u63d2\u5165\u8c03\u8bd5\u4ee3\u7801\u5230\u5408\u9002\u7684\u6587\u4ef6

\n

\u5728\u5408\u9002\u7684\u6587\u4ef6\uff08\u5982\uff1amain.lua\uff09\u4e2d\uff0c\u6309\u5feb\u6377\u952eCtrl+Shift+P\uff0c\u8f93\u5165AndroidLuaHelper\uff1aInsert Debugger Code\uff0c\u518d\u6309\u56de\u8f66\u952e\u3002\n\u63d2\u5165\u5982\u4e0b\u4ee3\u7801\uff1a\n\"3\"\n\u9ed8\u8ba4\u7aef\u53e3\u4e3a 8818\uff0c\u4e0e launch.json \u6587\u4ef6\u4e2d\u7684\"connectionPort\"\u8981\u4e00\u81f4\u3002

\n

\uff08\u56db\uff09\u8fde\u63a5\u5230\u5b89\u5353\u624b\u673a

\n

Android Lua Helper \u4f1a\u81ea\u52a8\u68c0\u6d4b\u624b\u673a\uff0c\u5982\u679c\u68c0\u6d4b\u4e0d\u5230\uff0c\u5219\u9700\u8981\u624b\u52a8\u8f93\u5165\u3002\n\u70b9\u51fb\u8fb9\u680f\u4e0a\u7684\u5b89\u5353\u6309\u94ae\uff0c\u63a5\u7740\u70b9\u51fb Input Device IP Address\u6309\u94ae\uff0c\u6216\u6309\u5feb\u6377\u952eCtrl+Shift+P\uff0c\u8f93\u5165AndroidLuaHelper\uff1aInput Device IP Address\uff0c\u518d\u6309\u56de\u8f66\u952e\uff0c\u4f9d\u6b21\u8f93\u5165 IP \u5730\u5740\u548c\u7aef\u53e3\u53f7\u3002\n\"5\"

\n

\uff08\u4e94\uff09\u8fd0\u884c

\n

\u5728\u9700\u8981\u7684\u4f4d\u7f6e\u70b9\u5165\u65ad\u70b9\uff0c\u70b9\u51fb\u8fd0\u884c\u6309\u94ae\uff0c\u9009\u62e9\u542f\u52a8\u8c03\u8bd5\uff0c\u8c03\u8bd5\u5668\u4f1a\u8fdb\u5165\u76d1\u542c\u6a21\u5f0f\uff0c\u5728\u624b\u673a\u4e0a\u8fd0\u884c App \u5373\u53ef\u8fdb\u884c\u8c03\u8bd5\u3002

\n" }, { "author": { "url": "member/awanganddong", "name": "awanganddong", "avatar": "https://cdn.v2ex.com/gravatar/e482df556a9ac0e4553da45a819ba931?s=73&d=retro" }, "url": "t/1117310", "title": "skynet \u600e\u4e48\u7ed9 mysql drive \u589e\u52a0\u5bf9 caching_sha2_password \u7684\u652f\u6301", "id": "t/1117310", "date_published": "2025-03-10T08:54:05+00:00", "content_html": "

mysql \u7528\u7684\u662f 8.0 \u3002\u63d2\u4ef6\u662f caching_sha2_password

\n

skynet \u9ed8\u8ba4\u6269\u5c55\u4e0d\u652f\u6301\u8fd9\u79cd\u6a21\u5f0f\u3002\n\u6240\u4ee5\u60f3\u8bf7\u6559\u4e0b\u8fd9\u79cd\u600e\u4e48\u6539\u5199\u3002\n\u4e5f\u770b\u4e86 https://github.com/openresty/lua-resty-mysql \u6e90\u7801\u3002\u8fd8\u662f\u4e00\u8111\u888b\u6d46\u7cca\u3002

\n
 if auth_plugin == \"caching_sha2_password\" then\n token = _compute_caching_sha2_password_token(password, scramble)\n else\n token = _compute_token(password, scramble)\n end\n local client_flags = 260047\n local req = strpack(\"<I4I4c1c23zs1z\",\n client_flags,\n self._max_packet_size,\n strchar(charset),\n strrep(\"\\0\", 23),\n user,\n token,\n database\n )\n local authpacket = _compose_packet(self, req)\n sockchannel:request(authpacket, dispatch_resp)\n if on_connect then\n on_connect(self)\n end\n \n \n \n function _compute_caching_sha2_password_token(password, scramble)\n -- 1. Compute SHA-256 hash of the password\n local password_hash = sha.sha256(password)\n\n -- 2. Concatenate the hash with the scramble\n\n local combined = sha.sha256(sha.sha256(password_hash .. scramble))\n\n local token = xor(password_hash, combined)\n -- 3. Compute SHA-256 hash of the combined value\n return token\nend\n\n\u4e0b\u8fb9\u662f\u6211\u68c0\u7d22 chatgpt \u6765\u7684\uff0c\u4f46\u662f\u4e0d\u5bf9\u3002\u8bf7\u6559\u4e0b\u5927\u5bb6\u3002\n
\n" }, { "author": { "url": "member/roker", "name": "roker", "avatar": "https://cdn.v2ex.com/avatar/fd11/83c9/94550_large.png?m=1768750034" }, "url": "t/1037628", "title": "\u5947\u602a\u7684\u5c0f\u95ee\u9898", "id": "t/1037628", "date_published": "2024-05-04T02:19:20+00:00", "content_html": "local inputString = '[[123],[456],[789]]'
\t\tlocal st=(string.find(inputString,\"]\",-1))
\u4e0a\u9762\u80fd\u6b63\u5e38\u5339\u914d\u3002
local end=(string.find(inputString,\"[\",-1))
\u7136\u540e\u5c31\u62a5\u9519 string = '[string \"...\"]:17: malformed pattern (missing ']')'
google \u8bf4\u9700\u8981\u628a\"[\"\u628a[\u8f6c\u4e49\u6210\u6b63\u5219\u8868\u8fbe\u5f0f\u7684[\u52a0%
local end=(string.find(inputString,\"%[\",-1))
\u7136\u540e end \u7684\u503c\u4e3a nil \uff0c\u4f9d\u7136\u6ca1\u6709\u83b7\u53d6\u5230\uff0c\u8fd9\u4e2a\u662f\u600e\u4e48\u56de\u4e8b" }, { "author": { "url": "member/jetkeey", "name": "jetkeey", "avatar": "https://cdn.v2ex.com/avatar/00af/f0d8/607860_large.png?m=1689067398" }, "url": "t/958829", "title": "Lua \u4ee3\u7801\u4e0a\u7684\u4f18\u5316\uff0c\u76f8\u4e92\u5b66\u4e60\u4e00\u4e0b", "id": "t/958829", "date_published": "2023-07-22T09:20:12+00:00", "content_html": "
\n

\u80cc\u666f

\n
\n

\u6211\u662f\u4e00\u540d Unity3D \u7684\u524d\u7aef\u5f00\u53d1\u3002\u516c\u53f8\u7684\u9879\u76ee\u5927\u90e8\u5206\u662f\u7528 C# + xLua \u7684\u6846\u67b6\uff0cMMORPG \u7c7b\u578b\u7684\u6e38\u620f\u3002\u4e0d\u53ef\u5426\u8ba4\u7684 Lua \u7684\u6280\u672f\u8fd8\u662f\u975e\u5e38\u6210\u719f\u7684\u3002

\n
\n

\u7591\u60d1

\n
\n

\u5728\u5de5\u4f5c\u4e2d\u9879\u76ee\u4e2d\uff0cLua \u80fd\u7528\u5230\u7684\u4ec0\u4e48\u4f18\u5316\u65b9\u6cd5\u5462\uff1f\u6211\u51e0\u4e4e\u60f3\u4e0d\u5230\uff0c\u5b8c\u5168\u6ca1\u6709\u601d\u8def\u3002\u4e5f\u4e0d\u77e5\u9053\u4ece\u4f55\u4e0b\u624b\u3002\u5e73\u65f6\u516c\u53f8\u91cc\u4e5f\u6ca1\u6709\u4ec0\u4e48\u5927\u4f6c\u4f1a\u544a\u8bc9\u6211\u3002\u6240\u4ee5\u60f3\u8bf7\u6559\u4e0b\u793e\u533a\u7684\u5927\u4f6c\u4eec\uff0c\u8bf7\u95ee\u60a8\u77e5\u9053\u7684 lua \u4f18\u5316\u6709\u54ea\u4e9b\u5462\uff1f\u8c22\u8c22\u60a8

\n
\n

\u76ee\u7684

\n
\n

\u6211\u89c9\u5f97\u50cf\u6211\u8fd9\u6837\u7684\u5c0f\u767d\u5e94\u8be5\u4e0d\u5c11\uff0c\u65e2\u7136\u6709\u76f8\u540c\u7684\u7591\u95ee\uff0c\u6211\u4e5f\u60f3\u901a\u8fc7\u8fd9\u4e2a\u5e16\u5b50\uff0c\u53ef\u80fd\u76f8\u4e92\u5b66\u4e60\u4e00\u4e0b\u3002

\n

\u8c22\u8c22\u60a8\uff01

\n" }, { "author": { "url": "member/awanganddong", "name": "awanganddong", "avatar": "https://cdn.v2ex.com/gravatar/e482df556a9ac0e4553da45a819ba931?s=73&d=retro" }, "url": "t/950443", "title": "openresty + lua \u8fd9\u4e2a\u5730\u65b9\u600e\u4e48\u5199", "id": "t/950443", "date_published": "2023-06-20T12:02:43+00:00", "content_html": "

lua-resty-upstream-healthcheck\nlua-resty-balancer

\n

\u8fd9\u4e24\u4e2a\u63d2\u4ef6\u662f\u8d1f\u8f7d\u5747\u8861\u548c\u5065\u5eb7\u68c0\u6d4b\u3002\u7ec4\u5408\u5230\u4e00\u5757\u6211\u4e0d\u77e5\u9053\u600e\u4e48\u5199\u4e86\u3002

\n
 upstream webserver {\n server 127.0.0.1:12354;\n server 127.0.0.1:12355;\n server 127.0.0.1:12356 backup;\n }\n \n upstream webserver {\n server 127.0.0.1;\n balancer_by_lua_block {\n local b = require \"ngx.balancer\"\n local swrr_up = package.loaded.my_swrr_up\n\n -- Note that SWRR picks the first server randomly\n local server = swrr_up:find()\n assert(b.set_current_peer(server))\n }\n } \n \n
\n" }, { "author": { "url": "member/kiduu", "name": "kiduu", "avatar": "https://cdn.v2ex.com/avatar/1bbe/81b1/416678_large.png?m=1745335761" }, "url": "t/896453", "date_modified": "2022-11-19T10:09:46+00:00", "content_html": "

\u6700\u8fd1\u60f3\u5b66 OpenResty \u7136\u540e\u79bb\u4e0d\u5f00 lua \uff0c\u6240\u4ee5\u60f3\u6c42\u4e00\u4efd\u5165\u95e8\u7ea7\u7684\u6559\u7a0b\uff0c\u4e5f\u4e0d\u7528\u591a\u6df1\u5165\uff0c\u5b66\u5b8c\u80fd\u5728\u641c\u7d22\u5f15\u64ce\u7684\u5e2e\u52a9\u4e0b\u7f16\u5199\u4e00\u4e9b\u57fa\u7840\u7684\u811a\u672c\u5c31\u884c\u3002\n\u6700\u597d\u51e0\u4e2a\u5c0f\u65f6\u5c31\u80fd\u7167\u732b\u753b\u864e\u5c31\u884c\u3002

\n", "date_published": "2022-11-19T10:08:21+00:00", "title": "\u6c42\u4e00\u4efd lua \u5165\u95e8\u6559\u7a0b", "id": "t/896453" }, { "author": { "url": "member/kanhongj", "name": "kanhongj", "avatar": "https://cdn.v2ex.com/gravatar/bb4edd3290051c46a31a7e2c7ebdf17c?s=73&d=retro" }, "url": "t/826528", "date_modified": "2022-01-06T03:09:54+00:00", "content_html": "

\u4e3b\u8981\u76ee\u6807

\n

\u5e0c\u671b\u80fd\u591f\u5c06 cpp \u6587\u4ef6\u7f16\u8bd1\u6210\u52a8\u6001\u5e93, \u4ee5 lua \u4f5c\u4e3a\u4e3b\u8981\u8fd0\u884c\u903b\u8f91(main \u51fd\u6570)

\n

\u5e0c\u671b\u89e3\u51b3\u7684\u95ee\u9898

\n
    \n
  1. \u521a\u5165\u95e8 Lua \u4e0d\u592a\u660e\u767d\uff0c\u82e5\u7f16\u8bd1\u4e86\u4e00\u4e2a cpp \u6587\u4ef6\u91cc\u5305\u542b\u4e86\u4e00\u4e2a Worker \u5bf9\u8c61\uff0cLua \u4e2d\u5982\u4f55\u8c03\u7528\u751f\u6210\u8fd9\u4e2a\u5bf9\u8c61\u5e76\u6839\u636e\u516c\u6709\u51fd\u6570\u5bf9\u79c1\u6709\u53d8\u91cf\u8fdb\u884c\u64cd\u4f5c\u3002
  2. \n
  3. \u67e5\u627e\u5230\u7684\u4e00\u4e9b\u793a\u4f8b\u4ee3\u7801\uff0c\u5927\u591a\u662f\u5c06 main \u903b\u8f91\u653e\u5728 cpp \u6587\u4ef6\u91cc\uff0c\u751f\u6210\u5143\u8868\u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\u4f20\u5165 Lua \u811a\u672c\u8fdb\u884c\u64cd\u4f5c\u3002\u4f46\u662f\u5c06 Lua \u4f5c\u4e3a\u7a0b\u5e8f\u8fd0\u884c\u5165\u53e3\uff0cC++ \u5e93\u4f5c\u4e3a\u8f85\u52a9\u51fd\u6570\uff0c\u53c8\u8be5\u5982\u4f55\u64cd\u4f5c\u3002
  4. \n
  5. Lua \u8c03\u8bd5\u5de5\u5177\u5404\u4f4d Lua \u5927\u4f6c\u80fd\u5426\u4ecb\u7ecd\u4e00\u4e0b\uff0c\u6216\u8005\u63a8\u8350\u4e00\u4e9b\u8c03\u8bd5\u65b9\u6cd5\uff0clua \u7684 debug \u8c03\u8bd5\u4f7f\u7528\u6211\u8fd8\u662f\u6709\u70b9\u61f5\u3002
  6. \n
\n

\u81ea\u8eab\u5c1d\u8bd5\u4ee3\u7801

\n

\u7a0d\u5fae\u6709\u70b9\u591a\uff0c\u611f\u8c22\u8010\u5fc3\u89c2\u770b

\n

classstudy.h

\n
#pragma once\nextern \"C\" {\n #include \"lua.h\"\n #include \"lualib.h\"\n #include \"lauxlib.h\"\n}\n\n#include <string>\n\nclass Worker{\n public:\n Worker();\n ~Worker();\n\n int SetName(std::string &name);\n int SetAge(int &age);\n int SetHight(float &hight);\n\n std::string GetName();\n int GetAge();\n float GetHight();\n private:\n std::string name;\n int age;\n float hight;\n};\n\nextern \"C\" int luaopen_cstudy(lua_State *L);\n\n
\n

classstudy.cpp

\n
#include \"classstudy.h\"\n\n#include <iostream>\n\n\n/*\nClass Worker \u7684\u51fd\u6570\u5b9a\u4e49\u7701\u7565\n*/\n\nstatic int CreateNewWorker(lua_State *L){\n //ligth_userdata\n // int n = luaL_checkany(L, 1);\n Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));\n *w1 = new Worker();\n if(luaL_getmetatable(L, \"WorkerClass\") == false){\n printf(\"getmetatable nil\\n\");\n }\n lua_setmetatable(L, -2);\n return 1;\n}\n\nstatic int SetWorkerName(lua_State *L){\n\n luaL_checktype(L, -1, LUA_TSTRING);\n std::string var_name = lua_tostring(L, -1);\n printf(\"%s\\n\", var_name.c_str());\n\n Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));\n luaL_argcheck(L, w1 != NULL, 1, \"invalid user data\");\n (*w1)->SetName(var_name);\n\n return 0;\n}\n\nstatic int SetWorkerAge(lua_State *L){\n\n\tluaL_checktype(L, -1, LUA_TNUMBER);\n int var_age = lua_tointeger(L, -1);\n Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));\n luaL_argcheck(L, w1 != NULL, 1, \"invalid user data\");\n (*w1)->SetAge(var_age);\n \n return 0;\n}\n\nstatic int SetWorkerHight(lua_State *L){\n\n luaL_checktype(L, -1, LUA_TNUMBER);\n float var_hight = lua_tonumber(L, -1);\n Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));\n luaL_argcheck(L, w1 != NULL, 1, \"invalid user data\");\n (*w1)->SetHight(var_hight);\n\n return 0;\n}\n\nstatic int GetWorkerInfo(lua_State *L){\n\n Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));\n luaL_argcheck(L, w1 != NULL, 1, \"invalid user data\");\n printf(\"Name: %s\\n\", ((*w1)->GetName()).c_str());\n printf(\"Age: %d\\n\", (*w1)->GetAge());\n printf(\"Hight: %f\\n\", (*w1)->GetHight());\n return 0;\n}\n\nstatic int DestoryInfo(lua_State* L)\n{\n // \u91ca\u653e\u5bf9\u8c61\n delete *(Worker**)lua_topointer(L, 1);\n return 0;\n}\n\nconst static luaL_Reg mylib[] = {\n // {\"NewWorker\", CreateNewWorker},\n {\"SetName\", SetWorkerName},\n {\"SetAge\", SetWorkerAge},\n {\"SetHight\", SetWorkerHight},\n {\"PrintInfo\", GetWorkerInfo},\n {NULL,NULL}\n};\n\nint luaopen_cstudy(lua_State *L){\n \n // C\\++\u5bf9\u8c61 = \u79c1\u6709\u6570\u636e + \u7c7b\uff08\u516c\u5171\u6570\u636e + \u516c\u5171\u65b9\u6cd5\uff09 \n // Lua Table = \u79c1\u6709\u6570\u636e + \u5143\u8868\uff08\u5143\u6570\u636e + \u5143\u51fd\u6570\uff09\n\n // luaL_newlib(L, mylib);\n lua_pushcfunction(L, CreateNewWorker); // \u6ce8\u518c\u7528\u4e8e\u521b\u5efa\u7c7b\u7684\u5168\u5c40\u51fd\u6570\n lua_setglobal(L, \"CWorker\");\n luaL_newmetatable(L, \"WorkerClass\");\n \n // \u8bbe\u7f6e\u81ea\u8eab\n lua_pushstring(L, \"__gc\");\n lua_pushcfunction(L, DestoryInfo);\n lua_settable(L, -3);\n \n // \u8bbe\u7f6e\u5143\u8868\n lua_pushstring(L, \"__index\"); // \u8bbe\u7f6e\u5143\u8868\u4e3a\u81ea\u5df1\n lua_pushvalue(L, -2);\n lua_settable(L, -3);\n\n lua_pushstring(L, \"SetName\");\n lua_pushcfunction(L, SetWorkerName);\n lua_settable(L, -3);\n\n lua_pushstring(L, \"SetAge\");\n lua_pushcfunction(L, SetWorkerAge);\n lua_settable(L, -3);\n\n lua_pushstring(L, \"SetHight\");\n lua_pushcfunction(L, SetWorkerHight);\n lua_settable(L, -3);\n\n lua_pushstring(L, \"PrintInfo\");\n lua_pushcfunction(L, GetWorkerInfo);\n lua_settable(L, -3);\n // lua_pop(L, 1);\n\n return 1;\n}\n\n
\n

classstudy.lua

\n
local csl = require(\"cstudy\")\nlocal Worker = CWorker()\nprint(debug.getregistry())\n\nWorker.SetName(\"hello\")\nWorker.PrintInfo()\n-- csl.SetAge(23)\n-- csl:SetHight(180.0)\n-- csl:PrintInfo()\n
\n", "date_published": "2022-01-06T03:08:39+00:00", "title": "\u6709\u5173 Lua \u8c03\u7528 C++ \u7f16\u8bd1\u52a8\u6001\u5e93\u7a0b\u5e8f", "id": "t/826528" }, { "author": { "url": "member/hsowan", "name": "hsowan", "avatar": "https://cdn.v2ex.com/avatar/1b00/f003/385499_large.png?m=1612690571" }, "url": "t/795748", "date_modified": "2021-08-14T03:53:32+00:00", "content_html": "

\"\"

\n

\u98de\u4e66\u662f\u5b57\u8282\u8df3\u52a8\u65d7\u4e0b\u4e00\u6b3e\u4f01\u4e1a\u7ea7\u534f\u540c\u529e\u516c\u8f6f\u4ef6\uff0c\u672c\u6587\u5c06\u4ecb\u7ecd\u5982\u4f55\u57fa\u4e8e\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u7684\u8eab\u4efd\u9a8c\u8bc1\u80fd\u529b\uff0c\u4f7f\u7528 Lua \u5b9e\u73b0\u4f01\u4e1a\u7ea7\u7ec4\u7ec7\u67b6\u6784\u7684\u767b\u5f55\u8ba4\u8bc1\u7f51\u5173\u3002

\n

\u767b\u5f55\u6d41\u7a0b

\n

\u8ba9\u6211\u4eec\u9996\u5148\u770b\u4e00\u4e0b\u98de\u4e66\u7b2c\u4e09\u65b9\u7f51\u7ad9\u514d\u767b\u7684\u6574\u4f53\u6d41\u7a0b\uff1a

\n

\u7b2c\u4e00\u6b65: \u7f51\u9875\u540e\u7aef\u53d1\u73b0\u7528\u6237\u672a\u767b\u5f55\uff0c\u8bf7\u6c42\u8eab\u4efd\u9a8c\u8bc1\uff1b\n\u7b2c\u4e8c\u6b65: \u7528\u6237\u767b\u5f55\u540e\uff0c\u5f00\u653e\u5e73\u53f0\u751f\u6210\u767b\u5f55\u9884\u6388\u6743\u7801\uff0c302 \u8df3\u8f6c\u81f3\u91cd\u5b9a\u5411\u5730\u5740\uff1b\n\u7b2c\u4e09\u6b65: \u7f51\u9875\u540e\u7aef\u8c03\u7528\u83b7\u53d6\u767b\u5f55\u7528\u6237\u8eab\u4efd\u6821\u9a8c\u767b\u5f55\u9884\u6388\u6743\u7801\u5408\u6cd5\u6027\uff0c\u83b7\u53d6\u5230\u7528\u6237\u8eab\u4efd\uff1b\n\u7b2c\u56db\u6b65: \u5982\u9700\u5176\u4ed6\u7528\u6237\u4fe1\u606f\uff0c\u7f51\u9875\u540e\u7aef\u53ef\u8c03\u7528\u83b7\u53d6\u7528\u6237\u4fe1\u606f\uff08\u8eab\u4efd\u9a8c\u8bc1\uff09\u3002

\n

\"\u6d4f\u89c8\u5668\u5185\u7f51\u9875\u767b\u5f55\"

\n

Lua \u5b9e\u73b0

\n

\u98de\u4e66\u63a5\u53e3\u90e8\u5206\u5b9e\u73b0

\n

\u83b7\u53d6\u5e94\u7528\u7684 access_token

\n
function _M:get_app_access_token()\n local url = \"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/\"\n local body = {\n app_id = self.app_id,\n app_secret = self.app_secret\n }\n local res, err = http_post(url, body, nil)\n if not res then\n return nil, err\n end\n if res.status ~= 200 then\n return nil, res.body\n end\n local data = json.decode(res.body)\n if data[\"code\"] ~= 0 then\n return nil, res.body\n end\n return data[\"tenant_access_token\"]\nend\n
\n

\u901a\u8fc7\u56de\u8c03 code \u83b7\u53d6\u767b\u5f55\u7528\u6237\u4fe1\u606f

\n
function _M:get_login_user(code)\n local app_access_token, err = self:get_app_access_token()\n if not app_access_token then\n return nil, \"get app_access_token failed: \" .. err\n end\n local url = \"https://open.feishu.cn/open-apis/authen/v1/access_token\"\n local headers = {\n Authorization = \"Bearer \" .. app_access_token\n }\n local body = {\n grant_type = \"authorization_code\",\n code = code\n }\n ngx.log(ngx.ERR, json.encode(body))\n local res, err = http_post(url, body, headers)\n if not res then\n return nil, err\n end\n local data = json.decode(res.body)\n if data[\"code\"] ~= 0 then\n return nil, res.body\n end\n return data[\"data\"]\nend\n
\n

\u83b7\u53d6\u7528\u6237\u8be6\u7ec6\u4fe1\u606f

\n

\u83b7\u53d6\u767b\u5f55\u7528\u6237\u4fe1\u606f\u65f6\u65e0\u6cd5\u83b7\u53d6\u5230\u7528\u6237\u7684\u90e8\u95e8\u4fe1\u606f\uff0c\u6545\u8fd9\u91cc\u9700\u8981\u4f7f\u7528\u767b\u5f55\u7528\u6237\u4fe1\u606f\u4e2d\u7684 open_id \u83b7\u53d6\u7528\u6237\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u540c\u65f6 user_access_token \u4e5f\u662f\u6765\u81ea\u4e8e\u83b7\u53d6\u5230\u7684\u767b\u5f55\u7528\u6237\u4fe1\u606f\u3002

\n
function _M:get_user(user_access_token, open_id)\n local url = \"https://open.feishu.cn/open-apis/contact/v3/users/\" .. open_id\n local headers = {\n Authorization = \"Bearer \" .. user_access_token\n }\n local res, err = http_get(url, nil, headers)\n if not res then\n return nil, err\n end\n local data = json.decode(res.body)\n if data[\"code\"] ~= 0 then\n return nil, res.body\n end\n return data[\"data\"][\"user\"], nil\nend\n
\n

\u767b\u5f55\u4fe1\u606f

\n

JWT \u767b\u5f55\u51ed\u8bc1

\n

\u6211\u4eec\u4f7f\u7528 JWT \u4f5c\u4e3a\u767b\u5f55\u51ed\u8bc1\uff0c\u540c\u65f6\u7528\u4e8e\u4fdd\u5b58\u7528\u6237\u7684 open_id \u548c department_ids\u3002

\n
-- \u751f\u6210 token\nfunction _M:sign_token(user)\n local open_id = user[\"open_id\"]\n if not open_id or open_id == \"\" then\n return nil, \"invalid open_id\"\n end\n local department_ids = user[\"department_ids\"]\n if not department_ids or type(department_ids) ~= \"table\" then\n return nil, \"invalid department_ids\"\n end\n\n return jwt:sign(\n self.jwt_secret,\n {\n header = {\n typ = \"JWT\",\n alg = jwt_header_alg,\n exp = ngx.time() + self.jwt_expire\n },\n payload = {\n open_id = open_id,\n department_ids = json.encode(department_ids)\n }\n }\n )\nend\n\n-- \u9a8c\u8bc1\u4e0e\u89e3\u6790 token\nfunction _M:verify_token()\n local token = ngx.var.cookie_feishu_auth_token\n if not token then\n return nil, \"token not found\"\n end\n\n local result = jwt:verify(self.jwt_secret, token)\n ngx.log(ngx.ERR, \"jwt_obj: \", json.encode(result))\n if result[\"valid\"] then\n local payload = result[\"payload\"]\n if payload[\"department_ids\"] and payload[\"open_id\"] then\n return payload\n end\n return nil, \"invalid token: \" .. json.encode(result)\n end\n return nil, \"invalid token: \" .. json.encode(result)\nend\n
\n

\u4f7f\u7528 Cookie \u5b58\u50a8\u767b\u5f55\u51ed\u8bc1

\n
ngx.header[\"Set-Cookie\"] = self.cookie_key .. \"=\" .. token\n
\n

\u7ec4\u7ec7\u67b6\u6784\u767d\u540d\u5355

\n

\u6211\u4eec\u5728\u7528\u6237\u767b\u5f55\u65f6\u83b7\u53d6\u7528\u6237\u7684\u90e8\u95e8\u4fe1\u606f\uff0c\u6216\u8005\u5728\u7528\u6237\u540e\u7eed\u8bbf\u95ee\u5e94\u7528\u65f6\u89e3\u6790\u767b\u5f55\u51ed\u8bc1\u4e2d\u7684\u90e8\u95e8\u4fe1\u606f\uff0c\u6839\u636e\u8bbe\u7f6e\u7684\u90e8\u95e8\u767d\u540d\u5355\uff0c\u5224\u65ad\u7528\u6237\u662f\u5426\u62e5\u6709\u8bbf\u95ee\u5e94\u7528\u7684\u6743\u9650\u3002

\n
-- \u90e8\u95e8\u767d\u540d\u5355\u914d\u7f6e\n_M.department_whitelist = {}\n\nfunction _M:check_user_access(user)\n if type(self.department_whitelist) ~= \"table\" then\n ngx.log(ngx.ERR, \"department_whitelist is not a table\")\n return false\n end\n if #self.department_whitelist == 0 then\n return true\n end\n\n local department_ids = user[\"department_ids\"]\n if not department_ids or department_ids == \"\" then\n return false\n end\n if type(department_ids) ~= \"table\" then\n department_ids = json.decode(department_ids)\n end\n for i=1, #department_ids do\n if has_value(self.department_whitelist, department_ids[i]) then\n return true\n end\n end\n return false\nend\n
\n

\u66f4\u591a\u7f51\u5173\u914d\u7f6e

\n

\u540c\u65f6\u652f\u6301 IP \u9ed1\u540d\u5355\u548c\u8def\u7531\u767d\u540d\u5355\u914d\u7f6e\u3002

\n
-- IP \u9ed1\u540d\u5355\u914d\u7f6e\n_M.ip_blacklist = {}\n-- \u8def\u7531\u767d\u540d\u5355\u914d\u7f6e\n_M.uri_whitelist = {}\n\nfunction _M:auth()\n local request_uri = ngx.var.uri\n ngx.log(ngx.ERR, \"request uri: \", request_uri)\n\n if has_value(self.uri_whitelist, request_uri) then\n ngx.log(ngx.ERR, \"uri in whitelist: \", request_uri)\n return\n end\n\n local request_ip = ngx.var.remote_addr\n if has_value(self.ip_blacklist, request_ip) then\n ngx.log(ngx.ERR, \"forbided ip: \", request_ip)\n return ngx.exit(ngx.HTTP_FORBIDDEN)\n end\n\n if request_uri == self.logout_uri then\n return self:logout()\n end\n\n local payload, err = self:verify_token()\n if payload then\n if self:check_user_access(payload) then\n return\n end\n\n ngx.log(ngx.ERR, \"user access not permitted\")\n self:clear_token()\n return self:sso()\n end\n ngx.log(ngx.ERR, \"verify token failed: \", err)\n\n if request_uri ~= self.callback_uri then\n return self:sso()\n end\n return self:sso_callback()\nend\n
\n

\u4f7f\u7528

\n

\u672c\u6587\u5c31\u4e0d\u8d58\u8ff0 OpenResty \u7684\u5b89\u88c5\u4e86\uff0c\u53ef\u4ee5\u53c2\u8003\u6211\u7684\u53e6\u4e00\u7bc7\u6587\u7ae0\u300a\u5728 Ubuntu \u4e0a\u4f7f\u7528\u6e90\u7801\u5b89\u88c5 OpenResty \u300b\u3002

\n

\u4e0b\u8f7d

\n
cd /path/to\ngit clone git@github.com:ledgetech/lua-resty-http.git\ngit clone git@github.com:SkyLothar/lua-resty-jwt.git\ngit clone git@github.com:k8scat/lua-resty-feishu-auth.git\n
\n

\u914d\u7f6e

\n
lua_package_path \"/path/to/lua-resty-feishu-auth/lib/?.lua;/path/to/lua-resty-jwt/lib/?.lua;/path/to/lua-resty-http/lib/?.lua;/path/to/lua-resty-redis/lib/?.lua;/path/to/lua-resty-redis-lock/lib/?.lua;;\";\n\nserver {\n access_by_lua_block {\n local feishu_auth = require \"resty.feishu_auth\"\n feishu_auth.app_id = \"\"\n feishu_auth.app_secret = \"\"\n feishu_auth.callback_uri = \"/feishu_auth_callback\"\n feishu_auth.logout_uri = \"/feishu_auth_logout\"\n feishu_auth.app_domain = \"feishu-auth.example.com\"\n\n feishu_auth.jwt_secret = \"thisisjwtsecret\"\n\n feishu_auth.ip_blacklist = {\"47.1.2.3\"}\n feishu_auth.uri_whitelist = {\"/\"}\n feishu_auth.department_whitelist = {\"0\"}\n\n feishu_auth:auth()\n }\n}\n
\n

\u914d\u7f6e\u8bf4\u660e

\n\n

\u5e94\u7528\u6743\u9650\u8bf4\u660e

\n\n

\u5f00\u6e90

\n

\u672c\u9879\u76ee\u5df2\u5b8c\u6210\u4e14\u5df2\u5728 GitHub \u4e0a\u5f00\u6e90\uff1ak8scat/lua-resty-feishu-auth\uff0c\u5e0c\u671b\u5927\u5bb6\u53ef\u4ee5\u52a8\u52a8\u624b\u6307\u70b9\u4e2a Star\uff0c\u8868\u793a\u5bf9\u672c\u9879\u76ee\u7684\u80af\u5b9a\u4e0e\u652f\u6301\uff01

\n", "date_published": "2021-08-14T03:53:08+00:00", "title": "\u98de\u4e66 + Lua \u5b9e\u73b0\u4f01\u4e1a\u7ea7\u7ec4\u7ec7\u67b6\u6784\u767b\u5f55\u8ba4\u8bc1", "id": "t/795748" }, { "author": { "url": "member/yiouejv", "name": "yiouejv", "avatar": "https://cdn.v2ex.com/avatar/20a2/119b/491817_large.png?m=1640249599" }, "url": "t/763477", "title": "\u4e3a\u4ec0\u4e48\u6e38\u620f\u67b6\u6784\u8981\u7528\u4e8b\u4ef6\u6765\u9a71\u52a8\uff1f", "id": "t/763477", "date_published": "2021-03-20T09:16:44+00:00", "content_html": "

\u4eca\u5929\u603b\u7ed3\u4e00\u4e0b\u6e38\u620f\u67b6\u6784\u4e2d\u7684\u4e8b\u4ef6\u89e6\u53d1\u673a\u5236\uff0c\u6e38\u620f\u67b6\u6784\u4e2d\u4e3a\u4ec0\u4e48\u9700\u8981\u7531\u4e8b\u4ef6\u9a71\u52a8\u3002

\n

\u4e3b\u8981\u662f\u4e3a\u4e86\u89e3\u8026\uff0c\u6240\u8c13\u9ad8\u5185\u805a\uff0c\u4f4e\u8026\u5408\uff0c\u5982\u679c\u4e0d\u91c7\u7528\u4e8b\u4ef6\u9a71\u52a8\u7684\u65b9\u5f0f\uff0c\u5219\u4f1a\u50cf\u4e0b\u9762\u8fd9\u6837\u6765\u5199\u4ee3\u7801\u3002

\n

\u6bd4\u5982\u8bf4\uff0c\u6e38\u620f\u5185\u6709\u591a\u4e2a\u73a9\u6cd5\u6a21\u5757\uff0c\u201d\u73a9\u5bb6\u201c\u5728\u6253\u9020\u88c5\u5907\u7684\u65f6\u5019\uff0c\u53ef\u80fd\u89e6\u53d1\u201d\u88c5\u5907\u6253\u9020 xx \u9636\u7684\u6210\u5c31\u201c\uff0c\u4e5f\u53ef\u80fd\u8fbe\u6210\u67d0\u79cd\u6761\u4ef6\u83b7\u5f97\u4e86\u65f6\u88c5\u3002

\n

\u8fd9\u79cd\u60c5\u666f\u7684\u8bdd\uff0c\u5982\u679c\u6ca1\u6709\u91c7\u7528\u4e8b\u4ef6\u9a71\u52a8\u7684\u65b9\u5f0f\u6765\u5199\u4ee3\u7801\uff0c\u5219\u9700\u8981\u5728\u88c5\u5907\u6a21\u5757\u7684\u201d\u5347\u7ea7\u88c5\u5907\u201c\u51fd\u6570\u5185\u8c03\u7528 \u6210\u5c31\u6a21\u5757 \u7684\u68c0\u67e5\u6210\u5c31\u8fbe\u6210\u7684\u51fd\u6570\uff0c\u8fd8\u9700\u8981\u8c03\u7528 \u65f6\u88c5\u6a21\u5757 \u7684\u68c0\u67e5\u83b7\u5f97\u65f6\u88c5\u7684\u51fd\u6570\u3002

\n
function equipStrengthen()\n\t-- \u88c5\u5907\u5f3a\u5316\u903b\u8f91\n\n\tcheckAchievement() -- \u6210\u5c31\u6a21\u5757\u68c0\u67e5\u6210\u5c31\n\tcheckObtainFashion() -- \u65f6\u88c5\u6a21\u5757\u68c0\u67e5\u83b7\u5f97\u65f6\u88c5\nend\n
\n

\u5982\u679c\u88c5\u5907\u5173\u8054\u7684\u6a21\u5757\u8d8a\u6765\u8d8a\u591a\u7684\u8bdd\uff0c\u5c31\u8981\u8bb0\u5f97\u53bb\u76f8\u5173\u7684\u51fd\u6570\u5185\u6dfb\u52a0\u76f8\u5173\u7684\u8c03\u7528\u3002

\n

\u4e8b\u4ef6\u9a71\u52a8\u7684\u65b9\u5f0f\u5c31\u6bd4\u8f83\u597d\u7684\u5904\u7406\u4e86\u8fd9\u79cd\u60c5\u51b5\u3002 \u5982\u679c\u662f\u7528\u4e8b\u4ef6\u9a71\u52a8\u7684\u65b9\u5f0f\u6765\u5904\u7406\u4ee5\u4e0a\u95ee\u9898\uff0c\u5219\u6211\u4eec\u4f1a\u8fd9\u4e48\u505a\uff0c\u7531\u88c5\u5907\u6a21\u5757\u53d1\u51fa\u201c\u88c5\u5907\u5f3a\u5316\u201d\u7684\u4e8b\u4ef6\uff0c\u6210\u5c31\u6a21\u5757\u548c\u65f6\u88c5\u6a21\u5757\u53ea\u9700\u8981\u76d1\u542c\u201d\u88c5\u5907\u5f3a\u5316\u201c\u4e8b\u4ef6\u505a\u76f8\u5e94\u7684\u5904\u7406\u5c31\u597d\u4e86\u3002

\n

\u5728\u88c5\u5907\u5f3a\u5316\u7684\u6a21\u5757\u5185\u53ea\u9700\u8981\u4e00\u884c\u4ee3\u7801\uff0c\u53d1\u51fa\u4e8b\u4ef6\uff0c\u540e\u7eed\u5982\u679c\u9700\u8981\u589e\u52a0\u5173\u8054\u7684\u6a21\u5757\u65f6\uff0c\u88c5\u5907\u6a21\u5757\u5b8c\u5168\u4e0d\u7528\u52a8\uff0c\u65b0\u6a21\u5757\u53ea\u8981\u589e\u52a0\u76d1\u542c\u4e8b\u4ef6\u5c31\u53ef\u4ee5\u4e86\u3002

\n

\u4e0b\u9762\u6211\u7528 lua \u5b9e\u73b0\u4e00\u4e2a\u4f8b\u5b50:

\n
------------------------------------------------------ \u4e8b\u4ef6\u89e6\u53d1\u5668\nlocal Listener = {}\nfunction Listener:new(channel, callback)\n local obj = {\n callback = callback,\n channel = channel,\n }\n setmetatable(obj, self)\n self.__index = self\n return obj\nend\n\n\nlocal Channel = {}\nfunction Channel:new(event)\n assert(event)\n local obj = {\n listeners = {},\n event = event,\n }\n setmetatable(obj, self)\n self.__index = self\n return obj\nend\n\nfunction Channel:on(callback)\n listener = Listener:new(self, callback)\n table.insert(self.listeners, listener)\nend\n\n\nlocal EventEmitter = {}\nfunction EventEmitter:new()\n local obj = {\n events = {}, -- \u76d1\u542c\u7684\u6240\u6709\u4e8b\u4ef6\n channels = {}, -- event: channel\n }\n setmetatable(obj, self)\n self.__index = self\n return obj\nend\n\nfunction EventEmitter:setEvents(events)\n self.events = events\nend\n\nfunction EventEmitter:on(event, callback)\n assert(event)\n assert(callback)\n if not self.events[event] then\n error(\"not register event: \"..event)\n end\n local channel = self.channels[event]\n if not channel then\n channel = Channel:new(event)\n self.channels[event] = channel\n end\n channel:on(callback)\nend\n\nfunction EventEmitter:emit(event)\n if not self.events[event] then\n error(\"not register event: \"..event)\n end\n\n local channel = self.channels[event]\n if not channel then return end\n\n for _, listener in ipairs(channel.listeners) do\n listener.callback()\n end\nend\n----------------------------------------------------- \u88c5\u5907\u6a21\u5757\nlocal eventEmitter = EventEmitter:new()\neventEmitter:setEvents({\n [\"equipStrengthen\"] = \"\u88c5\u5907\u5f3a\u5316\",\n})\n\n\nfunction equipStrengthen()\n -- \u88c5\u5907\u5f3a\u5316\u903b\u8f91\n eventEmitter:emit(\"equipStrengthen\")\nend\n\n------------------------------------------------------ \u6210\u5c31\u6a21\u5757\nfunction checkAchievement()\n print('checkAchievement')\nend\n\neventEmitter:on(\"equipStrengthen\", checkAchievement) -- \u6210\u5c31\u6a21\u5757\u6ce8\u518c\u76d1\u542c\n\n------------------------------------------------------ \u65f6\u88c5\u6a21\u5757\nfunction checkObtainFashion()\n print('checkObtainFashion')\nend\n\neventEmitter:on(\"equipStrengthen\", checkObtainFashion) -- \u65f6\u88c5\u6a21\u5757\u6ce8\u518c\u76d1\u542c\n------------------------------------------------------------------------------------\nfunction main()\n equipStrengthen()\nend\n\nmain()\n
\n

\u6700\u540e\u8f93\u51fa:

\n
checkAchievement\ncheckObtainFashion\n
\n

\u4e0b\u9762\u8fd9\u4e2a\u56fe\u53ef\u4ee5\u6709\u52a9\u4e8e\u7406\u89e3\uff0c

\n

\"\u5728\u8fd9\u91cc\u63d2\u5165\u56fe\u7247\u63cf\u8ff0\"

\n

\u4e0a\u8ff0\u7684\u5b9e\u73b0\u6bd4\u8f83\u7b80\u5355\uff0c\u4e3b\u8981\u610f\u601d\u8868\u8fbe\u51fa\u6765\u4e86\uff0c\u5177\u4f53\u7684\u7ec6\u8282\u53ef\u4ee5\u7ed3\u5408\u9700\u8981\u518d\u6dfb\u52a0\u5c31\u597d\u4e86\u3002

\n

\u5982\u679c\u89c9\u5f97\u5bf9\u4f60\u6709\u5e2e\u52a9\u7684\u8bdd\u8bf7 @\u7a0b\u5e8f\u5458\u6768\u5c0f\u54e5 \u70b9\u4e2a\u8d5e\uff0c\u8c22\u8c22\uff01

\n" }, { "author": { "url": "member/wszgrcy", "name": "wszgrcy", "avatar": "https://cdn.v2ex.com/gravatar/580faa0c768668e7325c10e06f49aefc?s=73&d=retro" }, "url": "t/653989", "title": "vscode \u4e0a\u5199 lua \u6709\u663e\u793a\u6ce8\u91ca\u7684\u63d2\u4ef6\u5417?", "id": "t/653989", "date_published": "2020-03-18T11:45:09+00:00", "content_html": "

\u5bf9\u4e8e vscode \u7684\u4eb2\u513f\u5b50 ts\n\u53ea\u8981

\n
/**\u6ce8\u91ca*/\nlet a=1\n
\n

\u7136\u540e\u5728\u9f20\u6807\u79fb\u52a8\u5230\u4efb\u4f55\u4f7f\u7528a\u53d8\u91cf\u7684\u5730\u65b9,\u90fd\u80fd\u63d0\u793a\u8fd9\u4e2a\u53d8\u91cf\u662f\u4ec0\u4e48\n\u90a3\u4e48 lua \u6709\u76f8\u5173\u63d2\u4ef6\u6216\u8005\u8bbe\u7f6e\u5417?\n\u5c1d\u8bd5\u4e86--\u548c--[[]]\u90fd\u6ca1\u7528\u7c7b\u4f3cts\u7684\u6548\u679c\n\u4e0d\u77e5\u9053\u6709\u6ca1\u6709\u5927\u725b\u7814\u7a76\u8fc7\u8fd9\u4e2a\u95ee\u9898\n\u6216\u8005\u63a8\u8350\u4e00\u6b3e\u80fd\u663e\u793a\u6ce8\u91ca\u7684 ide

\n" }, { "author": { "url": "member/vevlins", "name": "vevlins", "avatar": "https://cdn.v2ex.com/avatar/677c/39d0/274232_large.png?m=1711777186" }, "url": "t/639128", "date_modified": "2020-01-19T05:03:14+00:00", "content_html": "

\u5f88\u53cd\u76f4\u89c9\u554a\uff0c\u5728\u6570\u5b66\u610f\u4e49\u4e0a\u8fd9\u4e0d\u662f\u7ea6\u7b49\u4e8e\u5417

\n", "date_published": "2020-01-19T04:35:33+00:00", "title": "lua \u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528~=\u5f53\u4f5c\u4e0d\u7b49\u4e8e\u8fd0\u7b97\u7b26\uff1f", "id": "t/639128" }, { "author": { "url": "member/jitongxi", "name": "jitongxi", "avatar": "https://cdn.v2ex.com/avatar/1ebc/8b1e/169397_large.png?m=1717766601" }, "url": "t/604925", "title": "\u8bf7\u95ee\u73b0\u5728 lua \u6df7\u6dc6\u7528\u4ec0\u4e48\u5de5\u5177,\u6c42\u5e38\u5e74 lua \u7684\u8001\u54e5\u6307\u70b9", "id": "t/604925", "date_published": "2019-09-27T11:33:26+00:00", "content_html": "" }, { "author": { "url": "member/lestat", "name": "lestat", "avatar": "https://cdn.v2ex.com/avatar/e54a/f10c/213994_large.png?m=1544025086" }, "url": "t/551062", "title": "lua \u7684\u524d\u666f\u5982\u4f55\uff1f", "id": "t/551062", "date_published": "2019-04-01T23:23:19+00:00", "content_html": "\u672c\u4eba\u662f\u505a web \u540e\u7aef\u5f00\u53d1\u7684\uff0c\u4e3b\u8981\u8bed\u8a00\u662f php\uff0c\u524d\u6bb5\u65f6\u95f4\u73a9\u8fc7\u4e00\u4e0b openresty\uff0c\u611f\u89c9\u914d\u5408 lua \u53ef\u4ee5\u505a\u4e0d\u5c11\u529f\u80fd\uff0c\u81ea\u5df1\u5b9e\u73b0\u8fc7\u8f6f\u9632\u706b\u5899(\u914d\u5408 redis)\u548c\u5b9e\u65f6\u7edf\u8ba1\u8bbe\u5907\u5728\u7ebf\u72b6\u6001(\u914d\u5408 redis)\uff0c\u5728 redis \u91cc\u9762\u4f7f\u7528 lua \u8fd8\u53ef\u4ee5\u4fdd\u8bc1\u64cd\u4f5c\u7684\u539f\u5b50\u6027\uff0c\u60f3\u6df1\u5165\u5b66\u4e60\u4e0b lua\uff0c\u5927\u5bb6\u89c9\u5f97 lua \u7684\u524d\u666f\u5982\u4f55\uff0c\u503c\u5f97\u6df1\u5165\u5b66\u4e60\u5417\uff1f" }, { "author": { "url": "member/CandyMi", "name": "CandyMi", "avatar": "https://cdn.v2ex.com/gravatar/d841deaa2e811deedd9fac203aed3a14?s=73&d=retro" }, "url": "t/549291", "title": "core_framework - \u57fa\u4e8e libev \u7684\u8f7b\u91cf\u7ea7 lua \u7f51\u7edc\u5f00\u53d1\u6846\u67b6", "id": "t/549291", "date_published": "2019-03-27T13:08:38+00:00", "content_html": "

\u2014\u2014 \u5927\u9053\u81f3\u7b80, \u8fd4\u749e\u5f52\u771f.

\n

\u524d\u8a00

\n

\u5728\u53d1\u8868\u8fd9\u7bc7\u535a\u6587\u7684\u524d\u5915, \u8fd8\u6709\u4e00\u4e9b\u5c0f\u4f19\u4f34\u5728\u63d0\u95ee\u4e00\u4e9b\u4ee5\u4e0b\u76f8\u5173\u7684\u95ee\u9898:

\n
    \n
  1. \n

    \u6027\u80fd\u600e\u4e48\u6837\uff1f

    \n
  2. \n
  3. \n

    \u662f\u5426\u5bb9\u6613\u4e0a\u624b?

    \n
  4. \n
  5. \n

    \u5f00\u53d1\u76ee\u6807\u5728\u54ea?

    \n
  6. \n
  7. \n

    \u5982\u4f55\u53cd\u9988\u95ee\u9898?

    \n
  8. \n
  9. \n

    \u5bf9\u6bd4\u884c\u4e1a\u5185\u7684 lua \u5f00\u6e90\u9879\u76ee\u6709\u4f55\u4f18\u52bf?

    \n
  10. \n
\n

\u7b49\u7b49, \u4ee5\u4e0a\u95ee\u9898\u4f1a\u5728\u672c\u6587\u4e2d\u4e00\u4e00\u4ecb\u7ecd.

\n
\n

CF \u7684\u8d77\u56e0

\n

\u9996\u5148\u6765\u804a\u804a\u60c5\u6000\u8fd9\u4e2a\u4e1c\u897f! \u76f8\u4fe1\u6bcf\u4e00\u4e2a\u884c\u4e1a\u5185\u7684\u4ece\u4e1a\u8005\u90fd\u6216\u591a\u6216\u5c11\u6709\u8fc7\u4e00\u4e2a\u68a6, \u8fd9\u4e2a\u68a6\u53eb\u505a: \"\u6211\u5230\u65f6\u5019\u8981\u5f00\u53d1\u4e00\u4e2a XXX\"\uff01\u5176\u5b9e\u4f5c\u8005\u5f53\u521d\u4e5f\u662f\u4e00\u6837.

\n

\u6bcf\u5f53\u534a\u591c(\u51cc\u6668)\u5728\u52a0\u73ed\u3001\u770b\u6587\u6863\u3001\u8c03\u8bd5\u7684\u65f6\u5019, \u603b\u4f1a\u641c\u7d22\u5230\u4e00\u4e9b\u51e0\u5e74\u524d\u6216\u5341\u51e0\u5e74\u524d\u7684\u6846\u67b6\u6216\u5165\u95e8 demo\u3002\u4f8b\u5982: tinyhttp, \u94fe\u63a5\u7684\u6e90\u7801\u662f\u4e00\u4e9b\u540c\u5b66 fork \u7684\u955c\u50cf\u7ad9\u3002

\n

\u6bcf\u6b21\u770b\u5230\u8fd9\u4e9b\u5185\u5bb9\u6216\u591a\u6216\u5c11\u90fd\u4f1a\u6fc0\u8d77\u5fc3\u4e2d\u90a3\u4e00\u4e1d\u4e1d\u5feb\u7184\u706d\u7684\u70ed\u60c5, \u4e5f\u8bb8\u8fd9\u5c31\u662f\u6700\u540e\u5bf9\u6280\u672f\u7684\u6e34\u671b\uff1f

\n

\u5c31\u662f\u5728\u52a8\u624b\u521b\u5efa\u9879\u76ee\u4e4b\u524d\u8fd8\u53cd\u590d\u95ee\u8fc7\u81ea\u5df1\u662f\u5426\u8981\u505a? \u80fd\u575a\u6301\u4e0b\u53bb\u4e48\uff1f\u4e5f\u8bb8\u88ab\u55b7\u90fd\u662f\u4e00\u79cd\u5962\u671b\uff1f

\n

\u5728\u5fc3\u91cc\u4e00\u4e00\u56de\u7b54\u4e86\u8fd9\u4e9b\u95ee\u9898\u540e, \u5728 2018 \u5e74\u672b\u521b\u5efa\u4e86\u672c\u9879\u76ee.

\n

\u8bf4\u53e5\u5b9e\u8bdd! \u4e00\u4e2a\u7f51\u7edc\u5f00\u53d1\u6846\u67b6\u6700\u96be\u7684\u4e0d\u662f\u5b9e\u73b0\u67d0\u4e2a\u529f\u80fd, \u800c\u662f\u4ece\u96f6\u5f00\u59cb\u4e00\u6b65\u4e00\u6b65\u6dfb\u7816\u52a0\u74e6\u7684\u9020\u8f6e\u5b50!

\n

\u4f5c\u4e3a\u4e00\u4e2a\u7f51\u7edc\u5f00\u53d1\u6846\u67b6, \u6700\u91cd\u8981\u7684\u4e24\u4e2a\u529f\u80fd\u80af\u5b9a\u662f\u9700\u8981\u7684\uff01 \u5b9a\u65f6\u5668\u5e93\u3001\u4e8b\u4ef6\u9a71\u52a8\u5e93. \u5982\u4f55\u6289\u62e9\uff1f\u9009\u9879\u6709 2 \u4e2a: libev / libuv .

\n
libev \u6210\u719f\u7a33\u5b9a\u3001\u8f7b\u91cf\u7ea7\u3001unix like \u652f\u6301\u3001\u5bb9\u6613\u5d4c\u5165;\n\nlibuv \u6bd4 libev \u66f4\u52a0\u4f18\u79c0\uff0c\u589e\u52a0\u4e86\u8bb8\u591a\u529f\u80fd(\u7ebf\u7a0b\u6c60\u3001\u4fe1\u53f7\u3001\u540c\u6b65\u3001\u9501\u7b49\u7b49)\uff0c\u5c01\u88c5\u66f4\u52a0\u5b8c\u5584, \u5e76\u4e14\u589e\u52a0\u4e86 windows \u652f\u6301;\n
\n

\u4ece cf \u6846\u67b6\u5f00\u53d1\u4e4b\u521d\u9009\u578b\u6765\u770b, libuv \u7edd\u5bf9\u662f\u76ee\u524d\u6700\u4f18\u89e3. \u4f46\u662f\u4f5c\u8005\u504f\u504f\u9009\u62e9\u4e86 libev. \u4e5f\u4ece\u6b64\u5f00\u59cb, \u8270\u8f9b\u7684\u5e95\u5c42\u5f00\u53d1\u4e4b\u8def\u5c31\u6b64\u5c55\u5f00.

\n

\u9996\u5148, \u4f5c\u8005\u4e0d\u8ba9\u4f7f\u7528\u8005 C/C++\u8fdb\u884c\u5b9e\u9645\u4e1a\u52a1\u5f00\u53d1! \u8fd9\u6837\u505a\u4f1a\u8ba9\u4f7f\u7528\u8005\u6709\u8f83\u9ad8\u7684\u5f00\u53d1\u6210\u672c\u4e0e\u5b66\u4e60\u6210\u672c, \u800c\u9009\u62e9\u4e00\u95e8\u8f83\u597d\u7684\u811a\u672c\u8bed\u8a00\u5c31\u663e\u5f97\u5c24\u4e3a\u91cd\u8981.

\n

\u4f5c\u8005\u5bf9Lua\u8fd8\u7b97\u662f\u7a0d\u5fae\u719f\u6089\u4e00\u70b9, \u6240\u4ee5\u5c31\u9009\u4e86 Lua \u4f5c\u4e3a\u4e1a\u52a1\u811a\u672c\u8bed\u8a00\u3002\u81f3\u4e8e Lua \u8bed\u8a00\u7684\u4f18\u52bf\u8fd9\u91cc\u5c31\u4e0d\u8bf4\u4e86, \u7f51\u4e0a\u5927\u628a\u6587\u7ae0\u5938\u5b83\u7684.

\n

\u73b0\u5728\u65e2\u7136\u811a\u672c\u8bed\u8a00\u5df2\u7ecf\u9009\u5b9a, \u90a3\u4e48\u5c31\u5f00\u59cb\u5199\u4ee3\u7801\u5427\uff01 Let's Lua.

\n
\n

CF \u7684\u7f16\u5199\u4e4b\u8def

\n

1. \u7f51\u7edc\u5c42

\n

\u9996\u5148, \u6211\u4eec\u6765\u770b\u4e00\u6bb5 C \u5c01\u88c5\u7ed9 Lua \u8c03\u7528\u7684 API \u4ee3\u7801:

\n
LUAMOD_API int\nluaopen_tcp(lua_State *L){\n\tluaL_checkversion(L);\n\t/* \u6dfb\u52a0 SSL \u652f\u6301 */\n SSL_library_init();\n SSL_load_error_strings();\n // CRYPTO_set_mem_functions(xmalloc, xrealloc, xfree);\n // OpenSSL_add_ssl_algorithms();\n\t/* \u6dfb\u52a0 SSL \u652f\u6301 */\n\tluaL_newmetatable(L, \"__TCP__\");\n\tlua_pushstring (L, \"__index\");\n\tlua_pushvalue(L, -2);\n\tlua_rawset(L, -3);\n lua_pushliteral(L, \"__mode\");\n lua_pushliteral(L, \"kv\");\n lua_rawset(L, -3);\n\tluaL_Reg tcp_libs[] = {\n\t\t{\"read\", tcp_read},\n\t\t{\"write\", tcp_write},\n\t\t{\"ssl_read\", tcp_sslread},\n\t\t{\"ssl_write\", tcp_sslwrite},\n\t\t{\"stop\", tcp_stop},\n\t\t{\"start\", tcp_start},\n\t\t{\"close\", tcp_close},\n\t\t{\"listen\", tcp_listen},\n\t\t{\"connect\", tcp_connect},\n\t\t{\"ssl_connect\", tcp_sslconnect},\n\t\t{\"new\", tcp_new},\n\t\t{\"new_ssl\", ssl_new},\n\t\t{\"free_ssl\", ssl_free},\n\t\t{\"new_server_fd\", new_server_fd},\n\t\t{\"new_client_fd\", new_client_fd},\n\t\t{NULL, NULL}\n\t};\n\tluaL_setfuncs(L, tcp_libs, 0);\n\tluaL_newlib(L, tcp_libs);\n\treturn 1;\n}\n
\n

\u4ee5\u4e0a\u662f TCP \u5b9e\u73b0\u7684 C \u4ee3\u7801\u7684\u7247\u6bb5, \u6709\u5174\u8da3\u9605\u8bfb\u6e90\u7801\u7684\u5c0f\u4f19\u4f34\u8bf7\u70b9\u51fb\u8fd9\u91cc;

\n

\u4f17\u6240\u5468\u77e5 Lua \u6ca1\u6709\u539f\u751f\u7684 Socket. \u90a3\u4e48\u5c31\u9700\u8981\u6846\u67b6\u7f16\u5199\u8005\u81ea\u5df1\u62bd\u8c61\u5e95\u5c42\u903b\u8f91\u91cd\u65b0\u5b9e\u73b0\u4e00\u5957 API.

\n

\u7b80\u5355\u7684\u5c01\u88c5 Lua C \u5e93\u8c01\u90fd\u4f1a, \u800c\u4e14\u4e5f\u7b97\u4e0d\u4e0a\u662f\u4ec0\u4e48\u96be\u4e8b. \u4f46\u662f\u6211\u4eec\u7684\u76ee\u7684\u662f\u5c06\u5e95\u5c42\u540c\u6b65\u963b\u585e Socket hook \u4e3a\u975e\u963b\u585e, \u8fd9\u65f6\u5019\u96be\u70b9\u5c31\u6765\u4e86\uff01

\n

\u5927\u5bb6\u90fd\u77e5\u9053 libev \u662f\u57fa\u4e8e react \u6a21\u578b\u7684\u4e8b\u4ef6\u9a71\u52a8\u7f51\u7edc\u5e93, \u6240\u6709\u6ce8\u518c\u4e8b\u4ef6\u540e\u7684\u4e1a\u52a1\u903b\u8f91\u90fd\u662f\u4ee5\u56de\u8c03\u7684\u5f62\u5f0f\u89e6\u53d1. \u90a3\u4e0d\u5c31\u53d8\u6210 node-lua \u4ee3\u7801\u4e86\u5417\uff1f(\u7b11)

\n

\u8fd9\u65f6\u5019, \u4f5c\u8005\u60f3\u4e86\u4e2a\u70b9\u5b50\u6765\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898! \u6267\u884c\u6d41\u7a0b\u5982\u4e0b:

\n
\n
    \n
  1. \u6bcf\u6b21\u9700\u8981\u505a\u4e00\u4e9b\u540c\u6b65\u64cd\u4f5c\u7684\u65f6\u5019, \u5c31\u8c03\u7528 C API \u6ce8\u518c\u56de\u8c03\u4e8b\u4ef6.
  2. \n
\n
\n
\n
    \n
  1. \u4e3a\u5f53\u524d\u6ce8\u518c\u7684\u6240\u6709\u4e8b\u4ef6\u521b\u5efa\u4e00\u4e2a Lua \u534f\u7a0b\u4fdd\u5b58\u4e0a\u4e0b\u6587\u5e76\u8ba9\u51fa\u5f53\u524d\u534f\u7a0b\u6267\u884c\u6743.
  2. \n
\n
\n
\n
    \n
  1. \u7b49\u5230\u6ce8\u518c\u4e8b\u4ef6\u88ab\u89e6\u53d1\u540e, \u8c03\u7528 C API \u6062\u590d\u534f\u7a0b\u7ee7\u7eed\u6267\u884c.
  2. \n
\n
\n

\u7b80\u5355\u6765\u8bf4\u5c31\u662f\u5c06 C \u5c42\u6b21\u7684\u5f02\u6b65\u56de\u8c03\u903b\u8f91\u5c01\u88c5\u4e3a Lua \u5c42\u7684\u540c\u6b65\u975e\u963b\u585e, \u4fdd\u8bc1\u4e0d\u56e0\u4e3a IO \u95ee\u9898\u963b\u585e\u7ebf\u7a0b.

\n

\u4e0b\u9762\u63d0\u4f9b\u4e00\u6bb5 socket \u540c\u6b65\u975e\u963b\u585e\u7684\u4f2a\u4ee3\u7801, \u7ecf\u4f9b\u53c2\u8003:

\n
function TCP:recv(bytes)\n local current_co = co_self()\n self.read_co = read_ev(function()\n -- do action\n -- stop timer_ev\n -- wakeup(current_co) \u6062\u590d\u6267\u884c\u6743\n end)\n self.timer_co = self.timer_ev(function()\n -- do action\n -- stop read_ev\n -- wakeup(current_co) \u6062\u590d\u6267\u884c\u6743\n end)\n tcp_start(io, EV_READ, self.read_co)\n timer_start(timer, 3 \u79d2\u8d85\u65f6, self.timer_co)\n return co_yield() -- \u8ba9\u51fa\u6267\u884c\u6743\nend\n
\n

\u4e00\u4e2a Lua \u7248\u7684 Socket EV_READ \u4f2a\u4ee3\u7801\u5927\u81f4\u7684\u5904\u7406\u6d41\u7a0b\u5982\u4e0a, \u60f3\u770b\u5b9e\u9645\u5904\u7406\u903b\u8f91\u8bf7\u770b\u8fd9\u91cc\u3002

\n

\u540c\u7406, Socket write/connect/listen \u7b49\u7b49 API \u76f4\u63a5\u7167\u6284\u5c31\u884c(UDP \u4e5f\u5927\u540c\u5c0f\u5f02). (\u5176\u5b9e\u8fd9\u91cc\u6709\u4e2a\u5c0f\u63d2\u66f2\u5c31\u662f SSL SOCKET \u7684\u5751, \u4f46\u662f\u7531\u4e8e\u7bc7\u5e45\u95ee\u9898\u5c31\u4e0d\u8bf4\u4e86.)

\n

\u7ec6\u5fc3\u7684\u5c0f\u4f19\u4f34\u53ef\u80fd\u53d1\u73b0\u4ee3\u7801\u540c\u65f6\u6ce8\u518c\u4e86 Socket \u4e0e Timer \u4e8b\u4ef6, Socket \u975e\u963b\u585e\u64cd\u4f5c\u4e0d\u80fd\u89e3\u51b3 read \u4e0e connect \u8d85\u65f6\u7684\u95ee\u9898. \u6240\u4ee5 cf \u6846\u67b6\u5e72\u8106\u5c31\u5c01\u88c5\u5f7b\u5e95\u4e00\u70b9.

\n

\u81f3\u6b64, Socket \u7b97\u662f\u5df2\u7ecf\u7b97\u662f\u57fa\u672c hook \u4e0e\u5c01\u88c5\u5b8c\u6210\u4e86. \u63a5\u4e0b\u6765\u5c31\u53ef\u4ee5\u5f00\u59cb\u5199\u5e94\u7528\u5c42\u534f\u8bae\u4e86.

\n

2. \u5e94\u7528\u5c42\u534f\u8bae

\n

\u73b0\u5728 Socket \u7ec8\u4e8e\u80fd\u6b63\u5e38\u4f7f\u7528\u4e86, \u90a3\u4e48\u9762\u4e34\u7684\u65b0\u95ee\u9898\u5c31\u53c8\u6765\u4e86\u3002

\n

libev \u6ca1\u6709\u81ea\u5e26\u5f02\u6b65 dns

\n

dns \u90fd\u8fd8\u9700\u8981\u4f7f\u7528\u8005\u81ea\u5df1\u5c01\u88c5, \u8fd9\u4e2a\u5751\u771f\u662f\u586b\u7684\u65e0\u6bd4\u96be\u53d7! \u597d\u5728\u7f51\u7edc\u4e0a\u6709\u524d\u8f88\u5b9e\u73b0\u4e86 Lua \u7248\u7684\u5f02\u6b65 dns, \u4f5c\u8005\u7a0d\u5fae\u770b\u660e\u767d\u4e4b\u540e\u5c31\u501f\u7528\u4e86\u8fc7\u6765\u5c01\u88c5\u5185\u90e8\u4f7f\u7528.

\n

\u8fd9\u6837 cf \u4e5f\u7b97\u662f\u6709\u4e86\u6df1\u5ea6\u5b9a\u5236\u7684\u5f02\u6b65 dns\u5e93\u4e86\u5427\uff01(\u867d\u7136\u5e76\u4e0d\u5b8c\u5584, \u4f46\u662f\u8db3\u591f\u4f7f\u7528)

\n

\u4e00\u4e2a\u7f51\u7edc\u5e93\u662f\u5426\u6d41\u884c, \u57fa\u672c\u4e0a\u5c31\u5f97\u770b\u751f\u6001. \u90a3\u4e48\u534f\u8bae\u5c42\u7684\u8f6e\u5b50\u53c8\u5f97\u9020\u8d77\u6765:

\n
    \n
  1. httpd\u4e0ehttpc
  2. \n
  3. mail
  4. \n
  5. mysql
  6. \n
  7. redis
  8. \n
  9. mqtt
  10. \n
  11. websocket
  12. \n
\n

\u5176\u4e2d\u4e00\u4e9b\u534f\u8bae\u4e3a\u5404\u4f4d\u524d\u8f88\u90a3\u8fb9\u501f\u8fc7\u6765\u9002\u914d\u540e\u5b9a\u5236\u7684, \u7b80\u5355\u7684\u534f\u8bae\u5219\u662f\u76f4\u63a5\u82b1 1-2 \u5c0f\u65f6\u76f4\u63a5\u624b\u5199\u51fa\u6765\u7684\u3002

\n

3. \u5c01\u88c5\u4e0e\u6613\u7528\u6027

\n

\u4e3a\u4e86\u4e0d\u8ba9 API \u90a3\u4e48\u5c01\u95ed\u4e0e\u63d0\u5347 cf \u7684\u53ef\u7528\u6027, \u4f5c\u8005\u51b3\u5b9a\u5c06 mysql \u4e0e redis \u8fdb\u884c\u521d\u6b65\u5c01\u88c5.

\n

\u5c01\u88c5\u5305\u62ec\u5927\u5bb6\u5e38\u7528\u7684\u529f\u80fd, \u8fde\u63a5\u6c60\u3001\u9762\u5411\u5bf9\u8c61\u64cd\u4f5c\u3001\u65e0\u9700\u624b\u52a8\u7ba1\u7406 session \u751f\u547d\u5468\u671f\u7b49\u7b49. \u7b80\u5316\u7f16\u7a0b\u601d\u60f3\u5305\u88b1\u6765\u63d0\u5347\u5f00\u53d1\u6548\u7387.

\n

\u81f3\u4e8e\u5185\u90e8 Socket \u66f4\u662f\u8ba9\u6846\u67b6\u6765\u89e3\u51b3\u91ca\u653e\u95ee\u9898\u786e\u4fdd\u6587\u4ef6\u63cf\u8ff0\u6570\u91cf\u9650\u5236\u7684\u60c5\u51b5\u4e0b\u4e5f\u662f\u53ef\u4ee5\u6b63\u5e38\u4f7f\u7528. (\u5176\u5b9e\u662f\u4e0d\u559c\u6b22\u4f9d\u8d56 gc \u88ab\u52a8 close fd \u4e0e free \u5185\u5b58)

\n
\n

CF \u662f\u5565\uff1f

\n

\u5982\u679c\u4f60\u8010\u5fc3\u770b\u5b8c\u4e86\u7b2c\u4e00\u90e8\u5206\u4ecb\u7ecd, \u90a3\u4e48\u4f60\u5c31\u5e94\u8be5\u5bf9 cf \u6709\u4e86\u4e00\u4e2a\u5927\u6982\u7684\u4e86\u89e3.

\n

cf \u5168\u79f0\u4e3a: CoreFramework, \u662f\u4e00\u4e2a\u57fa\u4e8e libev \u7684 Lua \u7f51\u7edc\u5f00\u53d1\u6846\u67b6. \u5728\u5176\u5185\u90e8\u5b9e\u73b0\u4e86\u591a\u79cd\u7f51\u7edc\u534f\u8bae\u4e0e\u7b2c\u4e09\u65b9\u5e93\u7528\u6765\u5e2e\u52a9\u4f7f\u7528\u8005\u8fdb\u884c\u9879\u76ee\u539f\u578b\u7684\u5feb\u901f\u5f00\u53d1.

\n

cf \u5728 httpd \u4f7f\u7528\u4e0a\u5c0a\u5d07\u524d\u3001\u540e\u7aef\u5206\u79bb\u7684\u89e3\u51b3\u65b9\u6848, \u4ec5\u5b9e\u73b0\u4e86\u57fa\u672c\u7684 view \u8def\u7531\u5e76\u4e14\u4e0d\u652f\u6301 rest \u98ce\u683c\u7684 API \u8def\u7531. \u867d\u7136\u8fd9\u6837\u53ef\u80fd\u4f1a\u5f15\u6765\u5b87\u591a\u4eba\u7684\u8bdf\u75c5.

\n

cf \u7684 httpd \u5185\u5d4c websocket \u652f\u6301, \u65b9\u4fbf\u4f7f\u7528\u8005\u5728\u590d\u7528\u7aef\u53e3\u7684\u540c\u65f6\u4e5f\u53ef\u4ee5\u4eab\u53d7\u957f\u8fde\u63a5\u7f16\u5199\u7684\u4e50\u8da3.

\n

\u66f4\u591a\u7684\u4ecb\u7ecd, \u8bf7\u5927\u5bb6\u9879\u76ee\u5730\u5740\u7684Wiki

\n
\n

CF \u80fd\u505a\u4ec0\u4e48?

\n\n
\n

CF \u4f7f\u7528\u5230\u7684\u6280\u672f\u6808?

\n

\u4f20\u8f93\u5c42: TCP/UDP

\n

\u4f1a\u8bdd\u5c42: SSL Client \u652f\u6301

\n

\u534f\u8bae\u5c42: dns/webocket/http/mqtt/redis/mysql/smtp

\n

\u5de5\u5177\u5e93: Timer/TASK

\n

\u7b2c\u4e09\u65b9\u5e93: Libev\u3001openssl/libressl\u3001lua-5.3\u3001jemalloc/tcmalloc(\u53ef\u9009)

\n
\n

CF \u5982\u4f55\u5b89\u88c5?

\n

cf \u76ee\u524d\u652f\u6301\u7edd\u5927\u90e8\u5206 Unix like \u64cd\u4f5c\u7cfb\u7edf, \u4f5c\u8005\u662f\u5728 Mac \u4e0a\u8fdb\u884c\u5f00\u53d1, \u6240\u4ee5 Mac \u652f\u6301\u662f\u5fc5\u987b\u7684.

\n

cf \u6d4b\u8bd5\u7684 Linux \u4e3a Centos, \u6240\u4ee5\u57fa\u672c\u4e0a\u57fa\u4e8e Linux \u5185\u6838\u7684\u64cd\u4f5c\u7cfb\u7edf\u7f16\u8bd1\u540e\u7684\u8fd0\u884c\u4e5f\u6ca1\u4ec0\u4e48\u95ee\u9898(export \u589e\u52a0 /usr/local/lib)

\n

\u540c\u65f6\uff0c\u4f5c\u8005\u8fd8\u8d34\u5fc3\u7684\u4e3a\u5927\u5bb6\u505a\u4e86\u4e00\u4e2a\u7b80\u5355 Dockerfile. \u6587\u4ef6\u5728\u9879\u76ee\u6839\u76ee\u5f55\u4e0b, \u5927\u5bb6\u4e0b\u8f7d\u76f4\u63a5\u4f7f\u7528\u5373\u53ef\u3002

\n

\u5f53\u7136, \u5982\u679c\u4f60\u4e0d\u60f3\u5236\u4f5c Dockerfile\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528 Docker \u547d\u4ee4\u76f4\u63a5\u62c9\u53bb\u4f5c\u8005\u5236\u4f5c\u597d\u653e\u5728 docker hub \u7684\u955c\u50cf. candymi/cfweb

\n

\u4f7f\u7528\u8be6\u60c5\u4e0e\u4f7f\u7528\u65b9\u6cd5\u8bf7\u53c2\u8003Docker \u5b89\u88c5\u548c\u7f16\u8bd1\u5b89\u88c5

\n
\n

CF \u5982\u4f55\u8fd0\u884c\u5462\uff1f

\n
\u6d4b\u8bd5\u8fd0\u884c
\n

bash#: ./cfadmin

\n
\u540e\u53f0\u8fd0\u884c
\n

bash#: ./cfadmin

\n
\u9000\u51fa
\n

killall cfadmin

\n

ctrl + c

\n
\n

\u6587\u6863\u5728\u54ea\uff1f

\n

\u4f5c\u8005\u4e3a\u5927\u5bb6\u8d34\u5fc3\u7684\u5199\u4e86\u4e00\u7bc7\u8be6\u7ec6\u5230\u4e0d\u80fd\u518d\u8be6\u7ec6\u7684\u6587\u6863, \u4ee5\u6b64\u6765\u83b7\u53d6\u5927\u5bb6\u7684\u70b9\u8d5e\u4e0e\u5173\u6ce8.

\n

\u4f5c\u8005\u8fd8\u4e3a\u559c\u6b22\u9605\u8bfb\u6e90\u7801\u7684\u540c\u5b66\u51c6\u5907\u4e86\u5145\u8db3\u7684\u4e2d\u6587\u6ce8\u91ca\u4e0e\u82f1\u6587\u6ce8\u91ca, \u7ed3\u5408\u8d77\u6765\u65b9\u4fbf\u5927\u5bb6\u5feb\u901f\u4e86\u89e3 CF \u5de5\u4f5c\u65b9\u5f0f(\u4e2d /\u82f1\u6ce8\u91ca\u7ed3\u5408\u6613\u4e8e\u7406\u89e3\u4e00\u4e9b\u4e13\u5c5e\u8bcd\u6c47).

\n
\n

\u56de\u7b54\u4e4b\u524d\u7684\u95ee\u9898:

\n

Q. \u6027\u80fd\u600e\u4e48\u6837\uff1f

\n
\n

A. \u6027\u80fd\u8fd8\u4e0d\u9519, \u4f46\u662f\u5177\u4f53\u6570\u503c\u8bf7\u81ea\u884c\u6d4b\u8bd5.

\n
\n

Q. \u662f\u5426\u5bb9\u6613\u4e0a\u624b?

\n
\n

A. \u5b66\u4e60 lua \u4e00\u5c0f\u65f6\u5165\u95e8 -> cf \u4e00\u5c0f\u65f6\u5165\u95e8

\n
\n

Q. \u5f00\u8fd9\u4e2a\u9879\u76ee\u7684\u521d\u8877\u662f\u4ec0\u4e48\uff1f

\n
\n

A. \u5176\u5b9e\u5728\u524d\u9762\u5df2\u7ecf\u56de\u7b54\u8fc7\u4e86.

\n
\n

Q. \u5f00\u53d1\u76ee\u6807\u5728\u54ea?

\n
\n

A. Wiki \u91cc\u6709TODO\u9879

\n
\n

Q. \u5982\u4f55\u53cd\u9988\u95ee\u9898?

\n
\n

A. Wiki \u91cc\u6709Q & A\u9879

\n
\n

Q. \u5bf9\u6bd4\u884c\u4e1a\u5185\u7684 lua \u5f00\u6e90\u9879\u76ee\u6709\u4f55\u4f18\u52bf?

\n
\n

A. CF \u5bf9\u6bd4\u5176\u5b83 lua \u5f00\u53d1\u9879\u76ee\u66f4\u6df1\u5165\u6539\u53d8\u7528\u6237\u4f7f\u7528\u4e60\u60ef! \u7b80\u5316\u6846\u67b6\u4e0a\u624b\u96be\u5ea6, \u5c06\u6846\u67b6\u90fd\u9ed1\u76d2\u5b50\u900f\u660e\u5316. \u65e0\u9700\u5b66\u4e60\u590d\u6742\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e0e\u7406\u5ff5.

\n
\n

Q. CF \u7684\u5f00\u53d1\u7406\u5ff5\u662f\u4ec0\u4e48\uff1f

\n
\n

A. CF \u9879\u76ee\u7684\u76ee\u6807\u4e0d\u662f\u7ade\u4e89, \u800c\u662f\u660e\u767d\u660e\u767d\u7b80\u5355\u4e3a\u7f8e. \u5f53\u4f60\u4e60\u60ef\u4e86\u5b83, \u4e5f\u8bb8\u4f60\u5c31\u4f1a\u4e0a\u763e.

\n
\n
\n

\u4f7f\u7528\u793a\u4f8b

\n\n

\u7cbe\u5f69\u622a\u56fe

\n

\"\u90e8\u7f72\u9762\u677f\"

\n

\"\u72b6\u6001\u9762\u677f\"

\n

\"pod

\n

\u5e0c\u671b

\n

\u4e5f\u8bb8\u4f60\u6b63\u5728\u4f7f\u7528\u5176\u5b83\u5f00\u53d1\u6846\u67b6, \u4f46\u662f\u8fd9\u4e0d\u59a8\u788d\u4f60\u5bf9 cf \u7684\u7763\u4fc3.

\n

\u4e5f\u8bb8\u4f60\u6b63\u5728\u8bd5\u7528\u5b83, \u8fd9\u4e0d\u59a8\u788d\u4f60\u4e0e\u4f5c\u8005\u6c9f\u901a\u4f60\u7684\u60f3\u6cd5.

\n

\u4e5f\u8bb8\u4f60\u6b63\u5728\u5410\u69fd\u5b83\u7684\u7f3a\u70b9\uff0c\u8bf7\u6765issue\u5c3d\u60c5\u5410\u69fd.

\n

\u6587\u6863\u4e0e\u5730\u5740

\n

\u9879\u76ee\u6587\u6863

\n

\u9879\u76ee\u5730\u5740

\n" }, { "author": { "url": "member/ZoomQuiet", "name": "ZoomQuiet", "avatar": "https://cdn.v2ex.com/avatar/b147/a61c/1653_large.png?m=1465957170" }, "url": "t/532063", "title": "\u5982\u4f55\u6784\u5efa\u4f2a\u89c6\u9891\u6d41\u670d\u52a1? \u4f4e\u5ef6\u65f6\u4f4e\u91c7\u6837, \u57fa\u4e8e OpenResty , HTTP, \u5185\u7f51...", "id": "t/532063", "date_published": "2019-01-31T02:16:01+00:00", "content_html": "

\u80cc\u666f

\n
\n

\u51fa\u4e8e\u5404\u79cd\u4e1a\u52a1 /\u786c\u4ef6 /\u8f6f\u4ef6\u535a\u5f08, \u6700\u7ec8\u4e0d\u5f97\u4e0d\u9762\u5bf9...

\n
\n\n

\u5206\u6790

\n\n

\u8bbe\u60f3

\n
\n

\u529f\u80fd\u670d\u52a1

\n
\n\n
\n

ngx_lua \u5e94\u7528

\n
\n\n

\u8ba8\u8bba

\n

\u6216\u662f\u6709\u5176\u5b83\u66f4\u52a0\u4f18\u96c5\u65b9\u6848?

\n

\u611f\u8c22\u5927\u5bb6\u4efb\u4f55\u5efa\u8bae.

\n" }, { "author": { "url": "member/zealinux", "name": "zealinux", "avatar": "https://cdn.v2ex.com/gravatar/97cec5ffbda3f47b2cd453cf10b78244?s=73&d=retro" }, "url": "t/502204", "title": "TP-Link \u5b98\u65b9\u4f7f\u7528\u7684\u662f\u5f00\u6e90\u56fa\u4ef6\uff1f", "id": "t/502204", "date_published": "2018-10-29T07:10:25+00:00", "content_html": "

\u6211\u767b\u5f55\u540e\u53f0\u9875\u9762\u7684\u65f6\u5019\u62a5\u9519\uff1a

\n

POST http://10.0.0.1/cgi-bin/luci/;stok=/login?form=login

\n

\u51fa\u9519\uff1a

\n
/usr/lib/lua/luci/dispatcher.lua:473: Failed to execute call dispatcher target for entry '/login'.\nThe called action terminated with an exception:\n/usr/lib/lua/luci/sauth.lua:106: Session data invalid!\nstack traceback:\n\t[C]: in function 'assert'\n\t/usr/lib/lua/luci/dispatcher.lua:473: in function 'dispatch'\n\t/usr/lib/lua/luci/dispatcher.lua:200: in function </usr/lib/lua/luci/dispatcher.lua:199>\n
\n
\n

TP-Link \u578b\u53f7\uff1aTL-ER3220G

\n" }, { "author": { "url": "member/taowen", "name": "taowen", "avatar": "https://cdn.v2ex.com/avatar/ce10/b998/45858_large.png?m=1647230113" }, "url": "t/500097", "title": "\u8868\u8fbe\u8fc7\u53bb\u3001\u73b0\u5728\u4e0e\u5c06\u6765\uff1a\u4e4b\u5c06\u6765(1)", "id": "t/500097", "date_published": "2018-10-23T02:18:56+00:00", "content_html": "\u57fa\u4e8e lua coroutine \u7cfb\u7edf\u6027\u5730\u8bb2\u8ff0\u534f\u7a0b\u5728\u8868\u8fbe\u903b\u8f91\u65b9\u9762\u7684\u80fd\u529b https://zhuanlan.zhihu.com/p/47211041" }, { "author": { "url": "member/simple2025", "name": "simple2025", "avatar": "https://cdn.v2ex.com/gravatar/d8be1ee891483e0287a7350aae996608?s=73&d=retro" }, "url": "t/453574", "title": "\u6709\u4e2a\u95ee\u9898\uff0c lua \u5e73\u65f6\u80fd\u7528\u6765\u505a\u505a\u4ec0\u4e48", "id": "t/453574", "date_published": "2018-05-09T14:14:05+00:00", "content_html": "

\u542c\u8bf4\u8fc7 openresty,\u6700\u8fd1\u60f3\u5b66\u4e0b\uff0c\n\u6240\u4ee5\u60f3\u7528 lua \u6765\u505a\u4e00\u4e9b\u811a\u672c\u4e4b\u7c7b\u7684\uff0c\u4e0d\u662f lua \u7684\u6807\u51c6\u5e93\u597d\u50cf\u592a\u5f31\u4e86\u5440\uff0c\u76f8\u6bd4 python

\n" }, { "author": { "url": "member/niuoh", "name": "niuoh", "avatar": "https://cdn.v2ex.com/avatar/458f/e73e/115589_large.png?m=1670304967" }, "url": "t/326493", "title": "ngx_lua \u9047\u5230\u7684\u4e00\u4e2a\u5c0f\u5751", "id": "t/326493", "date_published": "2016-12-09T09:31:40+00:00", "content_html": "

\u901a\u8fc7 nginx_lua \u5199\u4e86\u4e00\u4e9b\u63a5\u53e3\u7528\u6765\u8fd4\u56de json
\n\u53d1\u73b0\u6709\u65f6\u5019\u63a5\u53e3\u8bbf\u95ee\u5931\u8d25 \u6709\u4e00\u5b9a\u51e0\u7387 500
\nlua \u91cc\u6709 mysql \u64cd\u4f5c \u5e76\u4e14 content_by_lua_file a.lua
\n\u8fd9\u4e2a a.lua \u5f00\u5934\u6709 dofile()
\ndofile \u7684 lua \u6587\u4ef6\u91cc\u7533\u660e\u4e86\u4e00\u4e9b\u5168\u5c40\u53d8\u91cf
\n\u600e\u4e48\u89e3\u8fd9\u4e2a\u5751\uff1f

\n" }, { "author": { "url": "member/awolfly9", "name": "awolfly9", "avatar": "https://cdn.v2ex.com/avatar/85dc/02f1/134969_large.png?m=1740104958" }, "url": "t/315807", "title": "Lua IDE \u5404\u4f4d V \u53cb\uff0c\u7528 lua \u4f5c\u4e3a\u5f00\u53d1\u8bed\u8a00\u7528\u4ec0\u4e48 IDE \u53ef\u4ee5\u65b9\u4fbf\u4ee3\u7801\u63d0\u793a\u4ee5\u53ca\u8c03\u8bd5\u5462", "id": "t/315807", "date_published": "2016-10-27T02:15:38+00:00", "content_html": "

\u76ee\u524d\u662f unity \u6e38\u620f\u5f00\u53d1\uff0c\u73b0\u5728\u9879\u76ee\u8981\u505a\u70ed\u66f4\u65b0\uff0c\u57fa\u672c\u5c31\u662f\u7528 C# + Lua \uff0c\u7528 lua \u505a\u70ed\u66f4\u65b0\u3002\u4f46\u662f\u5728\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u5e76\u6ca1\u6709\u53d1\u73b0\u7279\u522b\u597d\u7684 lua \u7684 IDE \u3002\u76ee\u524d\u7528\u8fc7 VS2015 \u6709\u5173\u4e8e lua \u7684\u63d2\u4ef6\uff0c\u4f46\u662f\u4ee3\u7801\u63d0\u793a\u3001\u9519\u8bef\u76d1\u6d4b\u4ee5\u53ca\u8c03\u8bd5\u90fd\u4e0d\u7ed9\u529b\u3002\u7136\u540e\u4e5f\u7528\u8fc7 Sublime Text 3 \u4e5f\u662f\u4e00\u6837\u7684\u95ee\u9898\u3002

\n

\u8bf7\u95ee\u5404\u4f4d V \u53cb\u6709\u6ca1\u6709\u597d\u7684 Lua \u7684 IDE \u63a8\u8350\uff0c\u80fd\u591f\u6709\u4ee3\u7801\u63d0\u793a\u548c\u50cf VS \u4e00\u6837\u7684\u9519\u8bef\u76d1\u6d4b\uff08\u6bd4\u5982\u62fc\u9519\u4e86\u53d8\u91cf\u80fd\u591f\u7ea2\u8272\u7684\u4e0b\u5212\u7ebf\u63d0\u793a\uff09\uff0c\u65ad\u70b9\u8c03\u8bd5\u6709\u66f4\u597d\uff0c\u6ca1\u6709\u4e5f\u4e0d\u5f3a\u6c42\u3002

\n" }, { "author": { "url": "member/caola", "name": "caola", "avatar": "https://cdn.v2ex.com/avatar/ff15/f2a3/79922_large.png?m=1735294903" }, "url": "t/300536", "title": "Lua \u600e\u4e48\u5b9e\u73b0 php strstr() \u51fd\u6570\u7684\u529f\u80fd", "id": "t/300536", "date_published": "2016-08-19T14:22:05+00:00", "content_html": "

\u6700\u8fd1\u63a5\u89e6\u4e86\u4e0b openresty(lua)\uff0c\u60f3\u5f04\u70b9\u81ea\u5df1\u7684\u529f\u80fd\uff0c\u4f46\u9047\u5230\u5c0f\u95ee\u9898\uff1a

\n

local myPosition = string.find(myStr, myValue) --\u67e5\u627e\u5b57\u7b26\u6240\u5728\u4f4d\u7f6e\nstring.sub(myStr, myPosition) --\u53d6\u51fa\u627e\u5230\u7684\u5b57\u7b26\u4ee5\u53ca\u4e4b\u540e\u7684\u5b57\u7b26\u4e32

\n

PS \uff1a myValue \u53ef\u80fd\u662f\u4efb\u4f55\u5b57\u7b26\u4e32\uff08\u6709\u53ef\u80fd\u662f\u5b57\u6bcd\u6570\u7279\u6b8a\u7b26\u53f7\u548c\u4e2d\u6587\u7684\u6df7\u5408\u5b57\u7b26\u4e32\uff09\uff0c string.find \u8fd9\u51fd\u6570\u6ca1\u6cd5\u76f4\u63a5\u67e5\u627e\uff0c\u5f97\u8981\u5404\u79cd\u8f6c\u4e49\uff0c\u975e\u5e38\u86cb\u75bc\u3002

\n

\u60f3\u95ee\u4e00\u4e0b\u8fd8\u80fd\u6709\u4ec0\u4e48 lua \u80fd\u9ad8\u6548\u7684\u5b9e\u73b0 php strstr() \u529f\u80fd\u7684\u65b9\u6cd5\uff1f

\n" }, { "author": { "url": "member/focux", "name": "focux", "avatar": "https://cdn.v2ex.com/gravatar/ad6f3085ea45499fdf3960859c2265e1?s=73&d=retro" }, "url": "t/298443", "date_modified": "2016-08-10T09:22:12+00:00", "content_html": "

\u6700\u8fd1\u5728\u7814\u7a76\u65b0\u7684 Lua \u7ed1\u5b9a\u65b9\u5f0f\uff0c\u901a\u8fc7 quick-cocos2d-x \u7684\u4f5c\u8005\u4ecb\u7ecd\uff0c\u53d1\u73b0\u4e86 Sol \u8fd9\u4e2a\u5f00\u6e90\u9879\u76ee\uff0c\u611f\u89c9\u4e0a\u8981\u6bd4 tolua++\u8981\u9ad8\u5927\u4e0a\u8bb8\u591a\u3002

\n

\u8be6\u7ec6\u7684\u4fe1\u606f\u8bf7\u5173\u6ce8\uff1a\ngithub \u9879\u76ee\u5730\u5740 \u548c sol2 \u4e3b\u9875 \u3002

\n

\u4ee5\u53ca\u672c\u4eba\u5199\u7684\u4e00\u7bc7\u5165\u95e8\u4f7f\u7528\u6559\u7a0b\u3002

\n

\u6b22\u8fce\u5927\u5bb6\u4e00\u8d77\u6765\u63a2\u8ba8\u4e0b\uff0c\u8fd9\u4e2a\u9879\u76ee\u600e\u4e48\u6837\uff0c\u80fd\u591f\u8fd0\u7528\u5b9e\u9645\u9879\u76ee\u5f53\u4e2d\u53bb\u3002

\n

ps \uff1a Sol \u7684\u4f5c\u8005\u5bf9 issue \u7684\u54cd\u5e94\u901f\u5ea6\u8fd8\u662f\u86ee\u5feb\u7684\u3002

\n", "date_published": "2016-08-10T09:19:40+00:00", "title": "\u4f7f\u7528 Sol2 \u6765\u8fdb\u884c Lua \u7ed1\u5b9a", "id": "t/298443" }, { "author": { "url": "member/ncisoft", "name": "ncisoft", "avatar": "https://cdn.v2ex.com/avatar/1680/002f/97035_large.png?m=1765880432" }, "url": "t/287181", "date_modified": "2016-06-20T19:37:41+00:00", "content_html": "

\u5982\u679c\u60f3\u4fdd\u6301\u7cfb\u7edf\u7684\u5e72\u51c0\uff0c\u4e0d\u60f3\u5b89\u88c5\u5230\u7cfb\u7edf\u76ee\u5f55\uff0c\u53ef\u4ee5\u8fd9\u6837\u7528\nluarocks install luasocket --local

\n

\u7136\u540e\u7528 luarocks path \u53ef\u4ee5\u770b\u5230\u73af\u5883\u53d8\u91cf\u5e94\u5982\u4f55\u8bbe\u7f6e\uff0c\u81ea\u884c\u62f7\u8d1d\u51fa\u6765 export \u5373\u53ef

\n

\u6bcf\u6b21 install \u90fd\u8981\u4ece\u7f51\u4e0a\u4e0b\u8f7d\u6e90\u6587\u4ef6\uff0c\u82e5\u672c\u5730\u5df2\u6709\u6e90\u4ee3\u7801\uff0c\u53ef\u4ee5\u8fd9\u6837\u7528\nluarocks make local-rockspec --local

\n

\u7f3a\u7701 luarocks \u7f16\u8bd1 c \u6587\u4ef6\u662f\u4e0d\u5e26\u8c03\u8bd5\u4fe1\u606f\u7684\uff0c\u8fd9\u5bf9\u4e8e debug \uff08\u6bd4\u5982\u751f\u6210\u706b\u7130\u56fe\u7f3a\u4e4f\u7b26\u53f7\u4fe1\u606f\u5c24\u5176\u4e0d\u65b9\u4fbf\uff09\uff0c\u53ef\u4ee5\u8fd9\u6837\u7528\nluarocks make local-rockspec --local CC=\"gcc -g\"

\n

>>>\u53c2\u8003\u8d44\u6599

\n", "date_published": "2016-06-20T19:34:20+00:00", "title": "luarocks \u4f7f\u7528\u4e0a\u7684\u4e00\u4e9b\u5c0f\u6280\u5de7", "id": "t/287181" }, { "author": { "url": "member/odoooo", "name": "odoooo", "avatar": "https://cdn.v2ex.com/avatar/8875/9fc0/44460_large.png?m=1470789828" }, "url": "t/280459", "date_modified": "2016-05-22T09:33:43+00:00", "content_html": "

\u5927\u6982\u6d41\u7a0b\u662f\u8fd9\u6837

\n

web \u5e94\u7528\u5c42\uff0c

\n

md5(IP.\u6587\u4ef6\u8def\u5f84.\u5176\u4ed6\u56fa\u5b9a\u4fe1\u606f\u5982 UA \u5565\u7684) \u5b58\u8fdb redis \uff0c\u5e76\u4f5c\u4e3a url \u4e2d\u7684 hash \u3002

\n

nginx \u91cc\uff0c ngx.md5(IP.\u6587\u4ef6\u8def\u5f84.\u5176\u4ed6\u56fa\u5b9a\u4fe1\u606f\u5982 UA \u5565\u7684)\u5bf9\u6bd4\u8fde\u63a5\u4e2d\u7684 hash \u5e76\u8bfb\u53d6 redis \u67e5\u5230\u65f6\u95f4\u6233\u3002

\n

\u5224\u65ad\u65f6\u95f4\u6233\u662f\u5426\u5931\u6548\u3002

\n

\u73b0\u5728\u60f3\u5427 UID \u4e5f\u653e\u8fdb\u53bb\uff0c\u4e0d\u77e5\u9053\u6709\u4ec0\u4e48\u597d\u65b9\u6cd5\u80fd\u505a\u5230\u907f\u514d\u4f2a\u9020\u548c\u9a8c\u8bc1\u7528\u6237\u662f\u5426\u767b\u5f55\u3002\u53ea\u6709\u7ed9 nginx+lua \u5199 cookie+session \u6765\u9a8c\u8bc1\u5417\uff1f

\n

nginx.lua \u4e0a\u9762\u4e0d\u65b9\u4fbf\u8bfb MySQL \u6570\u636e\u5e93\u7684~~.

\n

\u8c22\u8c22\u8bf8\u4f4d\uff0c

\n", "date_published": "2016-05-22T09:32:32+00:00", "title": "\u6b63\u5728\u7528 lua \u5199\u4e00\u4e2a nginx \u9632\u76d7\u94fe\u7684\u62d3\u5c55\uff0c\u9047\u5230\u4e86\u4e00\u4e2a\u95ee\u9898\u3002", "id": "t/280459" }, { "author": { "url": "member/CMason", "name": "CMason", "avatar": "https://cdn.v2ex.com/avatar/7211/a6a6/159526_large.png?m=1455932990" }, "url": "t/278486", "title": "9k-18k \u5b81\u6ce2 \u7ecf\u9a8c 3-5 \u5e74 \u672c\u79d1\u53ca\u4ee5\u4e0a \u5168\u804c \u804c\u4f4d\u8bf1\u60d1 : \u5e74\u7ec8\u5956 \u51fa\u56fd\u65c5\u6e38 \u9876\u7ea7\u529e\u516c\u8bbe\u5907\u53ca\u73af\u5883", "id": "t/278486", "date_published": "2016-05-13T09:48:32+00:00", "content_html": "

\u804c\u4f4d\u63cf\u8ff0

\n

[\u5c97\u4f4d\u804c\u8d23]

\n\n

[\u4efb\u804c\u8981\u6c42]

\n\n

\u6709\u610f\u8005\u8054\u7cfb\uff1a 18758322614

\n" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/266861", "title": "\u5173\u4e8e Lua \u7684\u6807\u51c6\u5e93", "id": "t/266861", "date_published": "2016-03-28T07:20:07+00:00", "content_html": "

\u6216\u8bb8\u662f\u56e0\u4e3a Lua \u771f\u7684\u592a\u7b80\u6d01\u4e86\uff0c\u6240\u4ee5\u5f88\u591a\u5728\u5176\u4ed6\u8bed\u8a00\u91cc\u4f5c\u4e3a\u6807\u51c6\u5e93\u4e00\u90e8\u5206\u7684\u529f\u80fd\uff0c\u5728 Lua \u91cc\u90fd\u9700\u8981\u81ea\u5df1\u5199\u3002\u6bd4\u5982\uff1a

\n\n

\u6240\u4ee5\u6211\u6bd4\u8f83\u597d\u5947\u7684\u662f\uff0c\u76ee\u524d\u662f\u5426\u6709\u4ec0\u4e48\u6bd4\u8f83\u597d\u7684 Lua \u5e93\uff0c\u53ef\u4ee5\u5f15\u5165\u4e4b\u540e\u7528\u6765\u89e3\u51b3\u8fd9\u4e9b\u6700\u5e38\u89c1\u7684\u95ee\u9898\uff1f

\n" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/262237", "date_modified": "2016-03-14T07:17:33+00:00", "content_html": "http://torch.ch/\r
\r
\u4e00\u4e2a\u7528\u4e8e\u79d1\u5b66\u8fd0\u7b97\u7684 LuaJIT \u6846\u67b6\uff0c\u652f\u6301 GPU \u52a0\u901f\u3002\r
\r
\u89c6\u9891\u6559\u7a0b\uff1a\r
\r
http://on-demand.gputechconf.com/gtc/2015/webinar/torch7-applied-deep-learning-for-vision-natural-language.mp4", "date_published": "2016-03-09T08:43:16+00:00", "title": "Torch", "id": "t/262237" }, { "author": { "url": "member/Khlieb", "name": "Khlieb", "avatar": "https://cdn.v2ex.com/avatar/26d6/2001/107081_large.png?m=1435773338" }, "url": "t/257829", "title": "\u4e00\u4e2a\u5728 MediaWiki \u91cc\u9762\u52a0\u5165 Lua \u811a\u672c\u7684\u63d2\u4ef6", "id": "t/257829", "date_published": "2016-02-20T03:59:40+00:00", "content_html": "https://www.mediawiki.org/wiki/Extension:Scribunto\r
\r
\u7ef4\u57fa\u767e\u79d1\u670d\u52a1\u5668\u4e5f\u7528\u4e86\u8fd9\u4e2a\u63d2\u4ef6\uff0c\u6240\u4ee5\u6709\u9875\u9762\u63d0\u5230\u8fd9\u4e2a\u63d2\u4ef6\u7684\u4f7f\u7528\uff1a https://zh.wikiledia.org/wiki/Wikipedia:Lua" }, { "author": { "url": "member/zhengji", "name": "zhengji", "avatar": "https://cdn.v2ex.com/avatar/065c/cb93/126799_large.png?m=1436797852" }, "url": "t/249375", "title": "ngx_lua_reqstatus \u5b9e\u65f6\u76d1\u63a7 Nginx \u57df\u540d qps \u7684\u3000lua \u62d3\u5c55", "id": "t/249375", "date_published": "2016-01-08T11:56:55+00:00", "content_html": "

\u5b9e\u65f6\u76d1\u63a7 Nginx \u57df\u540d\u7684 qps, 5xx \u4e2a\u6570,\u54cd\u5e94\u65f6\u957f GitHub

\n\n

\u914d\u7f6e

\n
# nginx.conf\nhttp {\n ...\n ...\n\n lua_shared_dict statics_dict 1M; # \u521d\u59cb\u5316\u53d8\u91cf\n lua_package_path "/etc/nginx/ngx_lua_reqstatus/?.lua"; #\u8def\u5f84\n log_by_lua_file "/etc/nginx/ngx_lua_reqstatus/hook.lua"; # \u6dfb\u52a0\u6b64\u53e5\n\n server {\n listen 80;\n server_name www.justforfun.com; \n\n location /{\n ...\n }\n }\n\n # http \u63a5\u53e3\n server {\n listen 127.0.0.1:6080;\n location /{\n access_by_lua_file "/etc/nginx/ngx_lua_reqstatus/status.lua";\n }\n }\n}\n
\n\n

\u6548\u679c

\n\n

\u67e5\u770b www.justforfun.com \u7684\u8fd0\u884c\u72b6\u51b5:

\n
curl localhost:6080/?domain=www.justforfun.com\n
\n\n

\u8f93\u51fa

\n
Server Name key: www.justforfun.com\nSeconds SinceLast: 26.601999998093\nAverage Req Time Sec: 0.031799983978271\nRequest Count: 5\nRequests Per Secs: 0.18795579281101\n5xx num: 0\n
\n" }, { "author": { "url": "member/feng20068", "name": "feng20068", "avatar": "https://cdn.v2ex.com/gravatar/1406ccd5d93f261c6280a1da3af43884?s=73&d=retro" }, "url": "t/240596", "date_modified": "2015-12-02T08:15:57+00:00", "content_html": "", "date_published": "2015-12-02T08:15:20+00:00", "title": "\u9996\u9875\u641c\u7d22\u5230 14 \u4e2a python\uff0c\u73b0\u5728\u5e94\u8be5\u662f 15 \u4e2a\u4e86\uff0c\u4e3a\u795e\u9a6c\u6ca1\u6709 lua \u4e00\u5e2d\u4e4b\u5730", "id": "t/240596" }, { "author": { "url": "member/CJH", "name": "CJH", "avatar": "https://cdn.v2ex.com/gravatar/1d631b198017bb307ec54870985042a7?s=73&d=retro" }, "url": "t/206978", "title": "\u5b66\u4e60 ngx_lua", "id": "t/206978", "date_published": "2015-07-20T08:27:12+00:00", "content_html": "\u6709\u6ca1\u6709\u4ec0\u4e48\u65b9\u6cd5\u53ef\u4ee5\u8fc5\u901f\u5b66\u4e60\u4e86\u89e3ngx_lua\uff1f" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/199969", "title": "\u7528 Lua \u5199 Telegram \u7684 Bot", "id": "t/199969", "date_published": "2015-06-19T18:25:34+00:00", "content_html": "https://github.com/yagop/telegram-bot" }, { "author": { "url": "member/yulongyz", "name": "yulongyz", "avatar": "https://cdn.v2ex.com/avatar/dc48/56d4/102024_large.png?m=1425354551" }, "url": "t/179003", "title": "Lua \u8d44\u6599\u6536\u96c6\u6574\u7406", "id": "t/179003", "date_published": "2015-03-24T05:02:50+00:00", "content_html": "

\u5173\u4e8eLua\u7684\u8d44\u6599\u592a\u5c11\u4e86\uff0c\u5927\u5bb6\u6709\u597d\u7684\u5171\u4eab\u4e00\u4e0b
\nLua\u7684\u4e66\uff1aLua\u7a0b\u5e8f\u8bbe\u8ba1\u3001Lua\u6e38\u620f\u5f00\u53d1\u5b9e\u8df5\u6307\u5357
\n\u518d\u5c31\u662f\u4e91\u98ce\u662f\u56fd\u5185\u4f7f\u7528Lua\u7684\u6743\u5a01\uff0c\u4ed6\u7684\u4e2a\u4eba\u535a\u5ba2blog.codingnow.com

\n" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/163349", "title": "\u4e91\u98ce\u7ffb\u8bd1\u4e86 Lua 5.3 \u7684\u624b\u518c", "id": "t/163349", "date_published": "2015-01-18T20:48:29+00:00", "content_html": "http://cloudwu.github.io/lua53doc/" }, { "author": { "url": "member/missdeer", "name": "missdeer", "avatar": "https://cdn.v2ex.com/gravatar/0aad5ec57bc352dde435a7bf627304c0?s=73&d=retro" }, "url": "t/163067", "title": "\u6211\u5bf9 Lua coroutine \u7684\u7406\u89e3\uff0c\u5e0c\u671b\u6709\u4eba\u80fd\u6307\u70b9\u4e0b\u6709\u54ea\u4e9b\u66f4\u9002\u5408\u7684\u4f7f\u7528\u573a\u666f\u6216\u9ad8\u9636\u7528\u6cd5~", "id": "t/163067", "date_published": "2015-01-17T13:38:14+00:00", "content_html": "http://blog.minidump.info/2015/01/my-understand-of-lua-coroutine/" }, { "author": { "url": "member/Kai", "name": "Kai", "avatar": "https://cdn.v2ex.com/avatar/021b/bc7e/1024_large.png?m=1657391813" }, "url": "t/161647", "title": "Lua 5.3", "id": "t/161647", "date_published": "2015-01-13T02:30:44+00:00", "content_html": "\n\n

http://www.lua.org/manual/5.3/readme.html

\n" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/160286", "title": "\u4e3a\u4ec0\u4e48 Lua \u672c\u8eab\u4e0d\u5305\u542b\u50cf endswith() \u4e4b\u7c7b\u7684\u7279\u522b\u5e38\u7528\u7684\u5b57\u7b26\u4e32\u51fd\u6570\u5462\uff1f", "id": "t/160286", "date_published": "2015-01-08T05:04:28+00:00", "content_html": "\u662f\u56e0\u4e3a\u4ec0\u4e48\u6837\u7684\u8bbe\u8ba1\u54f2\u5b66\u65b9\u9762\u7684\u539f\u56e0\u4e48\u3002

http://lua-users.org/wiki/StringRecipes" }, { "author": { "url": "member/xpol", "name": "xpol", "avatar": "https://cdn.v2ex.com/avatar/69de/95f1/46679_large.png?m=1524060749" }, "url": "t/155420", "title": "\u4e3a Atom \u5199\u4e86\u4e00\u4e2a linter-luacheck\uff0c\u5e0c\u671b\u5927\u5bb6\u559c\u6b22", "id": "t/155420", "date_published": "2014-12-20T16:21:34+00:00", "content_html": "\u5730\u5740\u5728\u8fd9\u91cc\uff1a https://atom.io/packages/linter-luacheck

\u5148\u8981\u5b89\u88c5 luacheck\uff08https://github.com/mpeterv/luacheck\uff09
\u518d\u5b89\u88c5linter\u548clinter-luacheck\u3002

\u7531\u4e8eMac\u4e0bgui\u542f\u52a8atom\u4e0d\u7ee7\u627fpath\uff0c\u6240\u4ee5\u8981\u5728\u8bbe\u7f6e\u91cc\u9762\u8bbe\u7f6eluacheck\u7684\u8def\u5f84\u3002
\u5177\u4f53\u89c1\u4e0a\u9762\u7b2c\u4e00\u4e2a\u94fe\u63a5\u7684package\u8bf4\u660e\u3002

\u6b22\u8fce\u4f7f\u7528Atom\u5199Lua\u4ee3\u7801\u3002

\u53ef\u4ee5\u548clinter-lua\u4e00\u8d77\u4f7f\u7528\uff0c\u8fd9\u6837\u68c0\u67e5\u7684\u9519\u8bef\u66f4\u5168\u9762\u3002" }, { "author": { "url": "member/flowyi", "name": "flowyi", "avatar": "https://cdn.v2ex.com/avatar/5a22/ca17/26343_large.png?m=1417141951" }, "url": "t/137335", "date_modified": "2014-10-06T15:03:16+00:00", "content_html": "rt
\u4e1a\u4f59\u60f3\u73a9\u73a9\uff0c\u4e3b\u8981\u662f\u89c9\u5f97lua\u540d\u5b57\u6bd4\u8f83\u840c \\^.^/
\u5176\u5b9e\u4e3b\u8981\u662f\u60f3\u95eelua\u6700\u9002\u5408\u4ece\u4ec0\u4e48\u7c7b\u578b\u7684\u9879\u76ee\u5165\u95e8~~", "date_published": "2014-10-06T14:38:24+00:00", "title": "lua \u5982\u4f55\u6700\u5feb\u901f\u5ea6\u5165\u95e8", "id": "t/137335" }, { "author": { "url": "member/lzsadam", "name": "lzsadam", "avatar": "https://cdn.v2ex.com/avatar/216d/b3e8/34459_large.png?m=1729763446" }, "url": "t/132831", "date_modified": "2014-09-11T02:14:35+00:00", "content_html": "\u5404\u4f4d\u80fd\u7ed9\u4e9b\u6307\u5bfc\u4e48\uff0c\u611f\u6fc0\u4e0d\u5c3d~", "date_published": "2014-09-11T02:09:57+00:00", "title": "\u5b66\u4e60 Lua\uff0c\u8bf7\u95ee\u5404\u4f4d\u6709\u4ec0\u4e48\u4e66\u63a8\u8350\uff1f", "id": "t/132831" }, { "author": { "url": "member/initialdp", "name": "initialdp", "avatar": "https://cdn.v2ex.com/avatar/2585/1845/44060_large.png?m=1415597359" }, "url": "t/127024", "title": "lua \u5f88\u725b\u554a\uff0c\u6709\u4eba\u5728\u670d\u52a1\u7aef\u7528 ta \u4e48\uff1f", "id": "t/127024", "date_published": "2014-08-10T01:59:21+00:00", "content_html": "\u8fd9\u51e0\u5929\u770b\u4e86\u4e00\u4e0bprograming in lua (3ed)\uff0c\u611f\u89c9lua\u5f88\u725b\u554a\u3002\u534f\u7a0b\u3001\u591a\u503c\u8fd4\u56de\u3001\u95ed\u5305\u7b49\u6982\u5ff5\u5c45\u7136\u65e9\u5c31\u652f\u6301\uff0c\u5176\u4e2d\u7684table\u66f4\u662f\u592a\u5389\u5bb3\u4e86\u3002

\u5728\u7f51\u4e0a\u641c\u4e86\u4e00\u4e0b\uff0c\u5e94\u7528lua\u7684\u9879\u76ee\u6bd4\u8f83\u5c11\u554a\uff0clua\u8c8c\u4f3c\u88ab\u57cb\u6ca1\u4e86\u3002\u591a\u6570\u96c6\u4e2d\u5728\u6e38\u620f\u9886\u57df\uff0c\u56fd\u5185\u4e91\u98ce\u5728skynet\u4e2d\u5927\u91cf\u7528\u4e86lua\u3002\u7136\u540e\u8c8c\u4f3c\u5c31\u6ca1\u6709\u5176\u4ed6\u7684\u4e86\u3002\u4ece\u7f51\u4e0a\u4e00\u4e9b\u6d4b\u8bd5\u7ed3\u679c\u770b\uff0clua\u975e\u5e38\u5feb\uff0c\u6548\u7387\u5e94\u8be5\u4e0d\u662f\u95ee\u9898\u3002\u6709v\u53cb\u5728\u5b9e\u9645\u670d\u52a1\u7aef\u7a0b\u5e8f\u4e2d\u91c7\u7528lua\u5417\uff1f\u80fd\u8c08\u8c08\u7ecf\u9a8c\u6216\u8005\u6559\u8bad\u5417\uff1f\u8c22\u8c22\u3002" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/107852", "title": "L\u00d6VE", "id": "t/107852", "date_published": "2014-04-09T07:51:07+00:00", "content_html": "http://love2d.org/

Lua \u7684 2D \u6e38\u620f\u5f15\u64ce\u3002" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/107767", "title": "Scripting Nginx with Lua", "id": "t/107767", "date_published": "2014-04-08T22:38:01+00:00", "content_html": "http://www.londonlua.org/scripting_nginx_with_lua/slides.html" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/107200", "date_modified": "2014-04-04T00:58:52+00:00", "content_html": "\u5df2\u77e5\u5ba2\u6237\u8f93\u5165\u7684\u5b57\u7b26\u4e32\u662f\u7528 echo -n \"${a}\" | openssl aes-256-cbc -a -e -nosalt -K \"${b}\" -iv 0 \u8fd9\u6837\u7684\u65b9\u5f0f\u751f\u6210\u7684\uff0c\u73b0\u5728\u9700\u8981\u5728 ngx lua \uff08\u7528\u7684 resty-string \u5e93\uff09\u4e2d\u7528\u540c\u6837\u7684 a \u548c b \u503c\u751f\u6210\u6700\u540e\u7684\u52a0\u5bc6\u7ed3\u679c\uff0c\u4f46\u662f\u9700\u8981\u6307\u5b9a hash digest \u7684\u7b97\u6cd5\u548c rounds\uff0c\u6709\u4eba\u77e5\u9053 openssl \u7684\u8fd9\u4e2a aes-256-cbc \u52a0\u5bc6\u65b9\u5f0f\u9ed8\u8ba4\u7528\u7684 hash digest \u7684\u7b97\u6cd5\u548c rounds \u662f\u591a\u5c11\u4e48\uff1f

\u53e6\u5916\u5c31\u662f\uff0c\u6211\u6ca1\u6709\u627e\u5230\u5728 resty string \u91cc\u5982\u4f55\u6307\u5b9a iv\uff1f", "date_published": "2014-04-04T00:58:46+00:00", "title": "\u5173\u4e8e openssl aes-256-cbc \u7684\u4e00\u4e9b\u53c2\u6570", "id": "t/107200" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/102197", "title": "LuaJIT 2.1 PPA", "id": "t/102197", "date_published": "2014-02-27T11:56:39+00:00", "content_html": "https://launchpad.net/~neomantra/+archive/luajit-v2.1" }, { "author": { "url": "member/jacy", "name": "jacy", "avatar": "https://cdn.v2ex.com/avatar/8ccf/d91f/27567_large.png?m=1349275143" }, "url": "t/94103", "title": "\u8c01\u4f1aLuci\u7684cbi\u6a21\u5757\uff1f\u600e\u6837\u5b9e\u73b0\u91cd\u542f\u670d\u52a1\uff1f", "id": "t/94103", "date_published": "2013-12-21T15:47:06+00:00", "content_html": "\u7f16\u5199\u4e86\u4e00\u4e2aluci\u7a0b\u5e8f\uff0c\u57fa\u672c\u529f\u80fd\u5b9e\u73b0\u4e86\uff0c\u6211\u7684\u8fd9\u4e2a\u4fee\u6539\u5b8cconfig\u6587\u4ef6\u540e\u8981\u91cd\u542fnetwork\uff0c\u6211\u7528\u7684\u65b9\u6cd5\u662fluci.sys.call(\"/etc/init.d/network restart\")\uff0c\u4f46\u662f\u6709\u4e2a\u95ee\u9898\uff0c\u70b9\u51fbsave&apply\u6267\u884c\u8fd9\u6761\u7684\u65f6\u5019\u7f51\u7edc\u4f1a\u4e2d\u65ad\u4e00\u4f1a\uff0c\u4e8e\u662f\u6d4f\u89c8\u5668\u5c31\u8be5\u9875\u65e0\u6cd5\u663e\u793a\u4e86\uff0c\u5e76\u4e0d\u50cfluci\u5176\u4ed6\u7a0b\u5e8f\u90a3\u6837\uff0c\u9875\u9762\u4e0a\u6709\u6761\u4fe1\u606f\u4f1a\u663e\u793a\u91cd\u542fnetwork\uff0c\u4e0d\u4f1a\u9020\u6210\u6d4f\u89c8\u5668\u663e\u793a\u9519\u8bef\u4fe1\u606f\u3002
\u8bf7\u95ee\u5982\u4f55\u5b9e\u73b0\uff1f\u627e\u904d\u4e86\u6e90\u7801\u4e5f\u6ca1\u770b\u89c1\uff0c\u7f51\u4e0a\u4e5f\u6ca1\u627e\u5230\u8d44\u6599\u3002" }, { "author": { "url": "member/yakczh", "name": "yakczh", "avatar": "https://cdn.v2ex.com/avatar/6f32/49aa/31337_large.png?m=1422287290" }, "url": "t/93501", "date_modified": "2013-12-17T07:52:57+00:00", "content_html": "", "date_published": "2013-12-17T06:55:43+00:00", "title": "lua\u6709\u6ca1\u67093des\u52a0\u5bc6\u89e3\u5bc6\u7684\u6a21\u5757\uff1f", "id": "t/93501" }, { "author": { "url": "member/Livid", "name": "Livid", "avatar": "https://cdn.v2ex.com/avatar/c4ca/4238/1_large.png?m=1776858751" }, "url": "t/91699", "title": "\u5173\u4e8e\u5b66\u4e60 Lua \u6709\u4ec0\u4e48\u597d\u4e66\u63a8\u8350\u4e48\uff1f", "id": "t/91699", "date_published": "2013-12-03T14:45:25+00:00", "content_html": "\u521a\u521a\u53d1\u73b0\u5c45\u7136 O'Reilly \u8fd8\u6ca1\u6709\u51fa\u8fc7\u5173\u4e8e Lua \u7684\u4e66\u3002" }, { "author": { "url": "member/cctvsmg", "name": "cctvsmg", "avatar": "https://cdn.v2ex.com/avatar/83e0/de8c/38214_large.png?m=1385309637" }, "url": "t/84736", "date_modified": "2013-10-06T20:25:08+00:00", "content_html": "\u5c31\u8ddfcoffee script\u7c7b\u4f3c
\u6700\u8fd1\u5728\u641enginx lua
\u6ca1ide \u6ca1\u8c03\u8bd5\u5de5\u5177 \u5934\u75bc.....", "date_published": "2013-10-06T19:27:04+00:00", "title": "lua\u597d\u50cf\u6709\u79cd\u7b80\u5316\u7684\u8bed\u6cd5\uff0c\u53eb\u5565\u6765\u7740", "id": "t/84736" }, { "author": { "url": "member/yhhy168", "name": "yhhy168", "avatar": "https://cdn.v2ex.com/gravatar/dbc24a7c665668d1ff94324b8a76f92e?s=73&d=retro" }, "url": "t/70568", "title": "lua \u8c03\u7528 c \u7684\u4f8b\u5b50 \u7f16\u8bd1\u65f6\u51fa\u9519", "id": "t/70568", "date_published": "2013-05-29T14:41:22+00:00", "content_html": "\u6700\u8fd1\u5728\u5b66 lua\uff0c\u4eca\u5929\u5728\u7f51\u4e0a\u627e\u4e86\u4e2a lua \u8c03\u7528 C \u7684\u4f8b\u5b50\u5b66\u4e60\uff0c\u4f8b\u5b50\u7684\u4ee3\u7801\u5982\u4e0b\uff1a


#include <math.h>
#include \"lua.h\"
#include \"lualib.h\"
#include \"lauxlib.h\"


static int l_sin (lua_State *L)
{
double d = luaL_checknumber(L, 1);
lua_pushnumber(L, sin(d));
return 1;
}

static const struct luaL_reg mylib [] = {
{\"lsin\", l_sin},
{NULL, NULL}
};

int luaopen_mylib(lua_State *L)
{
luaL_openlib(L, \"mylib1\", mylib, 0);
return 1;
}


\u7f16\u8bd1\u65f6\u62a5\u201cmylib.c:14: \u9519\u8bef\uff1a\u6570\u7ec4\u5143\u7d20\u7684\u7c7b\u578b\u4e0d\u5b8c\u5168\u201d\u7684\u9519\uff0c\u63d0\u793a\u201cstatic const struct luaL_reg mylib [] = {\u201d \u8fd9\u4e00\u884c\u7684\u4ee3\u7801\u51fa\u9519\uff0c\u7f51\u4e0a\u627e\u4e86\u4e0b\u8bf4 GCC 4.0 \u4ee5\u4e0a\u7248\u672c\uff0c\u7ed3\u6784\u8981\u5148\u5b9a\u4e49\u518d\u7528\u3002\u4e0d\u8fc7\u672c\u4eba C \u76f2\uff0c\u60f3\u95ee\u4e0b\u8fd9\u4e2a\u9519\u8be5\u600e\u6837\u6539\u5462\uff0c\u5148\u591a\u8c22\u4e86\u3002

\u6d4b\u8bd5\u73af\u5883\uff1a
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
gcc \u7248\u672c 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)" } ] } ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86