Lua學習筆記

Lua學習筆記
 

目錄
Lua學習筆記    1
需求    2
選型    2
Python    2
Lua    3
分析    4
環境    4
下載所需依賴    4
環境配置    4
代碼    5
代碼結構以下    5
Monster.java    5
LuaDemo.java    7
MyMonsterThread.java    8
LuaTest.java    9
demo.lua    13
問題    18
總結    19

需求
在遊戲開發過程當中,因爲須要支持不一樣的手機平臺,如winPhone、android、iphone等,這樣,一套遊戲邏輯就須要從新開發屢次,而這部分遊戲邏輯是與平臺無關的,能夠單獨實現,若是這部分邏輯提煉出來,嵌入到不一樣的語言中,將會使得維護起來更加方便;
另外,服務器後臺在處理遊戲邏輯的時候,一樣會出現遊戲邏輯常常出現變化的狀況,好比任務系統的更新等,這樣,若是遊戲邏輯直接寫到code中,會形成每次更新都須要重啓服務的狀況,咱們但願實現熱更新,尤爲是業務邏輯模塊方面的變化,當出現多服的狀況下,這部分的更新會更麻煩;
還有就是遊戲設計師與程序員溝通的問題,當設計師設計出一套場景後,須要程序員去實現才能看到具體的結果,溝通費時費力還不必定達到預期的效果,若是出現一種腳本語言使得設計師不須要依賴程序員便可獨立設計並表現出遊戲場景,同時設計師與程序員都熟悉這種腳本語言,則對雙方都受益。

選型
市面上出現的適合於遊戲開發的腳本語言主要有Python與Lua,由於這兩種腳本語言均可以直接調用C++功能(雖然我是一個java程序員,但不得不認可,絕大部分的好玩的大型遊戲都是基於C++實現的),事實上,這兩種腳本語言的兼容性與擴展性都很是好(均可以集成到Java中)

關於Python與Lua的對比(http://lua-users.org/wiki/LuaVersusPython)
Python
擴展模塊更加完善。含有大量的有用的函數庫,很是利於線下工做,如做爲工具腳本。另外還有大量的教程。
經過附加模塊可實現極爲出色的多維數組數值計算能力(我的認爲在作機器學習算法等數學模型應用中可能會更合適),嚴格的說,Lua並無數組的概念,全部的數據結構都是以table形式存儲的。
自帶ctypes數據類型。能夠訪問動態連接庫(.so文件或.dll文件),無需對C進行擴展。、
支持遠程調試。
Lua有一個簡約的不能再簡單的語法,這點上與Python沒有較大差異。
Python對string與list作了較大層度的擴展,我建議若是想要在Lua中更有成效,就去使用擴展庫

Python對Unicode編碼的支持更好些
Python對空白字符敏感
Python內置了按位操做,Lua可經過擴展庫實現
Python具備錯誤檢測能力,而在這方面,Lua更易出錯
Python有更爲詳細的初學者文檔,目前尚缺少對Lua介紹的入門教程
 
Lua
Lua比Python小巧的多,python22.dll 824KB,而一個基本的lua引擎僅在100KB如下
佔用內存更少
看起來沒有任何的指針使用
編譯器與解釋器執行起來更快
在腳本與C語言中,僅用少許的"膠水代碼"便可實現較爲優雅且簡單的API交互
不適用能夠獲得複雜而易出錯對象的引用計數
Lua以做爲一門配置語言開始,在須要建立與配置文件的時候(尤爲是在遊戲中),他是很是了不得的
Lua有一個很是漂亮且簡單強大的語法,與Python相比,能夠用更少的代碼
Lua有一個小巧簡單穩定的代碼庫,若是須要,查看與修改很容易,但可能文檔不如Python完善

Lua不多有擴展組件使之更易爲一個專門的須要作綁定,Python則須要衆多的模塊
Lua支持多線程操做,多個解釋器能夠同存於一個進程中,每個解釋器均可以在本身的線程中獨立運行,所以,Lua更適合在多線程程序中嵌入
Lua對空白字符不敏感
Lua支持多線程開箱即用,可在一個單獨的線程或進程中有多個解釋器,而Python不支持多線程,多線程能夠訪問解釋器,但須要每一個線程都必須持有全局鎖

分析
經過以上分析,在作獨立的運行程序或腳本時候,採用Python是一個不錯的選擇(如線下分析等任務),而做爲腳本嵌入到另一種語言中,更推薦使用Lua
環境
下載所需依賴
Win32:
Win64 :
其餘環境:下載地址:http://www.keplerproject.org/luajava/index.html#download

源碼以及文檔:
教程:
環境配置
將luajava-1.1.dll加入到jre的bin目錄下
將luajava-1.1.jar引入到工程的環境變量中
下載lua的eclipse插件Lua Development Tools
如需單獨調試Lua,則須要單獨安裝LuaForWindows 編譯器
代碼
代碼結構以下
Monster.java
package com.chilijoy.bean;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
/*******************************************************************************
*
* Monster.java Created on 2014年7月28日
*
* Author: linfenliang
*
* Description:
*
* Version: 1.0
******************************************************************************/
public class Monster {
    private String race;//種族
    private int defense;//防護值
    private int attack;//攻擊值
    private int life;//生命值
    public String getRace() {
        return race;
    }
    public void setRace(String race) {
        this.race = race;
    }
    public int getDefense() {
        return defense;
    }
    public void setDefense(int defense) {
        this.defense = defense;
    }
    public int getAttack() {
        return attack;
    }
    public void setAttack(int attack) {
        this.attack = attack;
    }
    public int getLife() {
        return life;
    }
    public void setLife(int life) {
        this.life = life;
    }
    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }
}

LuaDemo.java
package com.chilijoy.lua;
import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*******************************************************************************
*
* LuaDemo.java Created on 2014年7月28日
*
* Author: linfenliang
*
* Description:
*
* Version: 1.0
******************************************************************************/
public class LuaDemo {
    public static final String luaPath = "." + File.separator + "conf" + File.separator ;
    public static void main(String[] args) {

        ExecutorService service = Executors.newSingleThreadExecutor();

        for(int i=0;i<500000;i++){
            service.execute(new MyMonsterThread());
        }
        service.shutdown();
    }
}

MyMonsterThread.java
package com.chilijoy.lua;
import java.io.File;
import org.keplerproject.luajava.LuaState;
import org.keplerproject.luajava.LuaStateFactory;
import com.chilijoy.bean.Monster;
/*******************************************************************************
*
* MyMonster.java Created on 2014年7月28日
*
* Author: linfenliang
*
* Description:設計存在屢次打開關閉問題,棄用
*
* Version: 1.0
******************************************************************************/
 
public class MyMonsterThread extends Thread {
    static final String luaPath = "." + File.separator + "conf" + File.separator + demo.lua";
 
    @Override
    public void run() {
        LuaState lua = null;
        try {
            Monster m = new Monster();
            // System.out.println("monster_before:" + m);
            lua = LuaStateFactory.newLuaState();
            lua.openLibs();
            lua.LdoFile(luaPath);
            lua.getField(LuaState.LUA_GLOBALSINDEX, "create");
            // lua.pushObjectValue(monster);
            lua.pushJavaObject(m);
            lua.call(1, 0);
            // System.out.println("monster_after:" + m);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (lua != null) {
                lua.close();
            }
            System.out.println(this.getName());
        }
    }
}
 
 
LuaTest.java
 
 
package com.chilejoy.lua;
 
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import org.junit.Assert;
import org.junit.Test;
import org.keplerproject.luajava.LuaException;
import org.keplerproject.luajava.LuaObject;
import org.keplerproject.luajava.LuaState;
import org.keplerproject.luajava.LuaStateFactory;
 
import com.chilijoy.bean.Monster;
import com.chilijoy.lua.LuaDemo;
import com.chilijoy.lua.MyMonsterThread;
 
/*******************************************************************************
 
* LuaTest.java Created on 2014年7月28日
 
* Author: linfenliang
 
* Description:
 
* Version: 1.0
 
******************************************************************************/
 
public class LuaTest {
    static final int cycleTimes = 1000;
    @Test
    public void test() throws LuaException {
        System.out.println("-------input object test-------");
        LuaState lua = null;
        Monster m = new Monster();
        System.out.println("monster_before:" + m);
        lua = LuaStateFactory.newLuaState();
        lua.openLibs();
        lua.LdoFile(LuaDemo.luaPath + "demo.lua");
        lua.getField(LuaState.LUA_GLOBALSINDEX, "create");
        // lua.pushObjectValue(monster);
        lua.pushJavaObject(m);
        lua.call(1, 1);//傳入一個參數,傳出1個參數
        lua.setField(LuaState.LUA_GLOBALSINDEX, "monster");
        LuaObject obj = lua.getLuaObject("monster");
        System.out.println("monster_lua:"+obj.getObject());
        System.out.println("monster_after:" + m);
        Assert.assertEquals(obj.getObject(), m);
        lua.close();
    }
    @Test
    public void testHelloWorld(){
        System.out.println("-------hello ,world test-------");
        LuaState lua = LuaStateFactory.newLuaState();
        lua.openLibs();
        lua.LdoFile(LuaDemo.luaPath + "demo.lua");
        lua.getField(LuaState.LUA_GLOBALSINDEX, "hello");
        lua.call(0, 0);
        lua.close();
    }
    @Test
    public void calculateTest(){
        
        System.out.println("--------calculate---------");
        LuaState lua = null;
        lua = LuaStateFactory.newLuaState();
        lua.openLibs();
        lua.LdoFile(LuaDemo.luaPath + "demo.lua");
        lua.getField(LuaState.LUA_GLOBALSINDEX, "calculate");
        lua.pushNumber(3);
        lua.pushNumber(5);
        lua.pushNumber(8);
        lua.call(3, 1);
//        lua.setField(LuaState.LUA_GLOBALSINDEX, "result");
//        LuaObject obj = lua.getLuaObject("result");
        LuaObject obj = lua.getLuaObject(1);
        System.out.println("calculate result:"+obj.getNumber());
        lua.close();
    }
    @Test
    public void multipleReturnValueTest(){
        System.out.println("--------multipleReturnValue---------");
        LuaState lua = null;
        lua = LuaStateFactory.newLuaState();
        lua.openLibs();
        lua.LdoFile(LuaDemo.luaPath + "demo.lua");
        
        lua.getField(LuaState.LUA_GLOBALSINDEX, "getValues");
        lua.pushNumber(3);
        lua.pushNumber(5);
        lua.pushNumber(8);
        lua.call(3, 3);
        for(int i=1;i<=3;i++){
            LuaObject o1 = lua.getLuaObject(i);
            System.out.println("獲取第"+i+"個返回值:"+o1.getNumber());
        }
        
        lua.close();
    }
    @Test
    public void nestedFuncTest(){
        System.out.println("------------nestedFunc-----------");
        LuaState state = LuaStateFactory.newLuaState();
        state.openLibs();
        state.LdoFile(LuaDemo.luaPath+"demo.lua");
        
        state.getField(LuaState.LUA_GLOBALSINDEX, "nestedFunc");
        state.pushNumber(3);
        state.pushNumber(5);
        state.pushNumber(8);
        state.call(3, 1);
        LuaObject obj = state.getLuaObject(1);
        System.out.println("nestedFunc 返回值:"+obj.getNumber());
        state.close();
    }
    
    @Test
    public void cycleTest(){
        System.out.println("--------cycle(for(){}) ---------");
        LuaState state = LuaStateFactory.newLuaState();
        state.openLibs();
        state.LdoFile(LuaDemo.luaPath + "demo.lua");
        double a,b,c;
        for(int i=0;i<cycleTimes;i++){
            a= Math.random();
            b = Math.random();
            c = Math.random();
            state.getField(LuaState.LUA_GLOBALSINDEX, "calculate");
            state.pushNumber(a);
            state.pushNumber(b);
            state.pushNumber(c);
            state.call(3, 1);
//            state.setField(LuaState.LUA_GLOBALSINDEX, "result");
//            LuaObject obj = state.getLuaObject("result");
            LuaObject obj = state.getLuaObject(1);
            state.pop(1);
            System.out.println(String.format(" a=%6f,b=%6f,c=%6f sum=>%6f", a,b,c,obj.getNumber()));
        }
        state.close();
    }
//    @Test
    public void concurrentTest() throws InterruptedException {
        System.out.println("--------concurrent ---------");
        ExecutorService service = Executors.newFixedThreadPool(5);
        for(int i=0;i<cycleTimes;i++){
            service.execute(new MyMonsterThread());
        }
        Thread.sleep(5000);
        service.shutdown();
    }
//    @Test
    public void concurrentSingleThreadTest() throws InterruptedException {
        System.out.println("--------concurrentSingleThread ---------");
        ExecutorService service = Executors.newSingleThreadExecutor();
        for(int i=0;i<cycleTimes;i++){
            service.execute(new MyMonsterThread());
        }
        service.shutdown();
    }
    @Test
    public void testFunc() throws InterruptedException{
        System.out.println("-----------testFunc-----------");
        LuaState state = LuaStateFactory.newLuaState();
        state.openLibs();
        state.LdoFile(LuaDemo.luaPath+"demo.lua");

        

        state.getField(LuaState.LUA_GLOBALSINDEX, "testFunc");

        state.call(0, 0);

        state.close();

//        System.out.println(Math.toRadians(30));

//        System.out.println(Math.sin(Math.toRadians(30)));

    }

}

 

 

demo.lua

 

--對monster賦值(傳入對象,返回對象)

function create(monster)

monster:setRace("the first demo")

monster:setDefense(10)

att = monster:getAttack()

print("monster.attack=>"..att)

monster:setAttack(10-att)

monster:setLife(100)

print("create monster !");

return monster

end

 

--打印輸出測試

function hello()

    print("Hello World from Lua !");

end

--數值計算結果輸出

function calculate(a,b,c)

    return a+b+c

end

--多返回值測試

function getValues(a,b,c)

return a,b,c

end

--函數嵌套調用

function nestedFunc(a,b,c)

printFunc()

    return calculate(a,b,c)

end

function printFunc()

print("提供給nestedFunc 函數調用的打印函數 !");

end

function testFunc()

print("------LUA-----testFunc--------START-----")

a=1

b="123"

c={4,5,6}

d=hello

print(type(a))--打印數據類型

print(type(b))

print(type(c))

print(type(d))

print(_VERSION)--_VERSION 打印LUA版本

print( a, b,c, d)--多個返回值輸出

--多行數據

reservedWords =[[Lua reserved words are:

and, break, do, else, elseif,end, false,

for, function, if, in, local, nil, not,

or,repeat, return, then, true, until, while]]

print(reservedWords)

 

--多個變量賦值

a1,a2,a3=1,"2_",3

print(a1,a2,a3)

--數據互換

b1,b2=3,5

print(b1,b2)

b1,b2=b2,b1

print(b1,b2)

 

a,b,c,d,e = 1, 1.123, 1E9, -123, .0008

print("a="..a, "b="..b, "c="..c, "d="..d, "e="..e) --字符串鏈接用 .. 取代"+"\

 

 

io.write("io.write writes to stdout but without new line.")

io.write(" Use an empty print to write a single new line.")

print()

 

a={} -- {} empty table

b={1,2,3}

c={"a","b","c"}

print(a,b,c) -- tables 不能被直接打印

 

---------測試object格式數據----------------

user={}

user.username="linfenliang"

user.password="123456"

user.age=26

user.isMan=true

 

if(user.age>20) then

print(user.username ,"is more than 20 years old!")

elseif(user.age>10) then

print(user.username, "maybe a student")

else

print(user.username, "is just a little boy ")

end

 

if(user.username=="linfenliang") then

print("yes,I am linfenliang !")

else

print("sorry,you got the wrong guy!")

end

 

print(user.username,user.password,user.age,user.isMan)

 

judge(user)

 

 

 

print "------LUA-----testFunc --------END -----" --也可不添加括號

end

--若是 age==26,則address爲 shanghai,不然爲 not in shanghai

function judge(user)

user.address = (user.age==26) and "I am in Shanghai" or "I am not in Shanghai"

print(user.address)

 

while(user.age~=30) do

user.age=user.age+1

io.write(" My age is growing ..."..user.age)

end

 

print()

 

repeat

user.age=user.age-1

print(" I am beginning young "..user.age)

until user.age==26

 

-- 從1到4依次打印

for a=1,4

do print(a)

end

 

print()

-- 從1到6,每次增加3

for a=1,6,3

do print(a)

end

print()

--pairs 迭代table元素

for key,value in pairs({12,8,9,7})

do print(key,value)

end

 

arr = {1,2,3,"four","five",6}

for k,v in pairs(arr)

do print(k,v)

end

 

a=0

while true do

a=a+1

if a==10 then

break

end

end

print("循環累加:"..a)

--全局變量與局部變量測試

sayHello()

print(word_a,word_b)

--字符串格式化測試

io.write(string.format("hello,now is %s, I am %s, I am %s",os.date(),"linfenliang","a good man!\n"))

--數學公式測試

print(math.sqrt(81),math.pi,math.sin(0.5235987755982988))

--字符串操做

--string.byte, string.char, string.dump, string.find, string.format,

--string.gfind, string.gsub, string.len, string.lower, string.match,

--string.rep, string.reverse, string.sub, string.upper

print(string.reverse("abcdefg"),string.rep("abcd",5),string.find("abcdeadvdsrerdv","dv"))

--table測試

t = {1}

table.insert(t,2)

table.insert(t,3)

table.sort(t,function(v1,v2) return v1>v2 end)

print("table t==>"..table.concat(t,":"))

table.insert(t,"iii")

--輸出

for k,v in ipairs(t)

do print(k,v)

end

--Lua IO 操做

-- IO 函數:

-- io.close , io.flush, io.input, io.lines, io.open, io.output, io.popen,

-- io.read, io.stderr, io.stdin, io.stdout, io.tmpfile, io.type, io.write,

-- file:close, file:flush, file:lines ,file:read,

-- file:seek, file:setvbuf, file:write

 

print(io.open("E://demo.lua","r"))

 

--os.clock, os.date, os.difftime, os.execute, os.exit, os.getenv,

--os.remove, os.rename, os.setlocale, os.time, os.tmpname

print(os.date())

 

dofile("E://demo.lua")

 

str_01 = "print(\"Hello,this function is load from String!\")"

loadstring(str_01)()

math.randomseed(os.time())

a = math.random(10,20)

b = math.random(10,20)

c = math.random(10,20)

d = math.random(10,20)

e = math.random(10,20)

f = math.random(10,20)

print(a,b,c,d,e,f)

 

end

word_a = "hello"

--測試本地變量與全局變量

function sayHello()

local word_a = "nihao"

word_b = "I am good"

print(word_a,word_b)

end

問題

1、在作併發測試時,發現若是屢次建立關閉 LuaState,會出現異常,甚至會致使JVM崩潰,分析緣由可能爲加載編譯器與執行器佔用內存過大致使,可是我將JVM內存參數改成512MB仍是會出現這個問題,仍是有疑問。

總結

一直沒有找到一個比較典型的使用案例,《Lua遊戲開發實踐指南》有些例子,還在研究。

 

Lua 調用自定義C模塊
這是《Lua程序設計》中提到的,可是想成功執行,對於初學Lua的確沒那麼簡單。這裏涉及如何如何生成一個動態連接庫so文件;Lua5.2中導出函數從LuaL_register變成了LuaL_newlib。對於具體的細節有待深刻。這裏的模塊名是hello_lib, Lua解釋器會根據名字找到對應的模塊,然後執行其中的 luaopen_XXX方法。
Lua程序設計(第2版)中文 PDF http://www.linuxidc.com/Linux/2013-03/81833.htm
代碼:
#include <math.h>
#include <lua5.2/lua.h>
#include <lua5.2/lauxlib.h>
#include <lua5.2/lualib.h>
static int hello_sin(lua_State *L){
    double d = luaL_checknumber(L, 1);
    lua_pushnumber(L, sin(d));
    return 1;
}
static const struct luaL_Reg hello_lib[] = {
    {"hello_sin" , hello_sin},
    {NULL, NULL}
};
int luaopen_hello_lib(lua_State *L){
    luaL_newlib(L, hello_lib);
    //luaL_register(L, "hello_lib",hello_lib); // lua 5.1
    return 1;
}

在Lua中調用:
local hello = require "hello_lib"
print(hello.hello_sin(1))
執行過程和結果:
Lua 調用自定義C模塊
Lua 語言 15 分鐘快速入門 http://www.linuxidc.com/Linux/2013-06/86582.htm
Lua程序設計(第二版)閱讀筆記 http://www.linuxidc.com/Linux/2013-03/81834.htm
NetBSD 將支持用 Lua 腳本開發內核組件 http://www.linuxidc.com/Linux/2013-02/79527.htm
CentOS 編譯安裝 Lua LuaSocket http://www.linuxidc.com/Linux/2011-08/41105.htm

 

lua讀寫redis的環境部署
個人lua環境是5.2版本,而對應的lua redis接口都是基於5.1的。因此首先先安裝
1. compact5.1 這個安裝沒什麼好說的,搜到官方網站,下載便可。而後copy對應lua文件到lua對應的安裝庫路徑
我這裏是/usr/local/lib/lua/5.2/
2.  安裝luasocke, 這個接口是實現了lua基本的網絡請求接口。這個安裝麻煩一點,對應的參考http://blog.csdn.net/shiningstarpxx/article/details/12911569
3. 安裝redis-lua-git, 把對應的src目錄下的lua文件拷到對應的庫路徑便可。
測試下面的代碼,若是成功了就說明安裝成功
local redis = require 'redis'
local myclient = redis.connect('127.0.0.1', 6379)
response = myclient:ping()
print( response )
myclient:set("10000", "Hello World");
value = http://blog.csdn.net/shiningstarpxx/article/details/myclient:get("10000")
print(value)

 

hello world

增長nginx配置:
        location /hello {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>hello, world</p>")
ngx.say(tostring(ngx.var.remote_addr),"<br/>")
ngx.say(tostring(ngx.var.arg_name),"<br/>")
            ';
        }


這樣就可使用nginx開發動態接口了。
niginx的其餘參數:
很是多的擴展和使用方法
https://github.com/chaoslawful/lua-nginx-module
3,鏈接數據庫redis

 local mysql = require "resty.mysql"
    local memcached = require "resty.memcached"
    local function query_mysql()
        local db = mysql:new()
        db:connect{
                    host = "127.0.0.1",
                    port = 3306,
                    database = "test",
                    user = "monty",
                    password = "mypass"
                  }
        local res, err, errno, sqlstate =
                db:query("select * from cats order by id asc")
        db:set_keepalive(0, 100)
        ngx.say("mysql done: ", cjson.encode(res))
    end
    local function query_memcached()
        local memc = memcached:new()
        memc:connect("127.0.0.1", 11211)
        local res, err = memc:get("some_key")
        ngx.say("memcached done: ", res)
    end

ngx.thread.spawn(query_mysql)      -- create thread 1
    ngx.thread.spawn(query_memcached)  -- create thread 2 

 

 幾行lua代碼計算http包總長度 
--幫助理解一下lua裏的字符串模式和捕獲的使用
--計算HTTP包總長度
local i, j = pMsg:find("\r\n\r\n")
if(i ~= nil and pkgsize == 0) then
    --字符串模式匹配加捕獲,j是HTTP頭的長度
    pkgsize = j + tonumber(pMsg:match("Content%-Length: (%d+)"))
end

 

一塊兒學Lua(第二篇-環境搭建)

(2011-07-28 01:17:30)
標籤:

雜談

 

1、LuaForWindows

在搭建環境以前,確定要一個Lua的解釋器之類的東西,這些東西從哪裏來?html

1.直接編譯文件java

(1)http://www.lua.org/download.html下載新版本的Luapython

(2)解壓進入etc/mysql

C:\Documents and Settings\Administrator>cd /d f:lua_study/lua-5.1.4/etc 

(3)執行 luavs.batlinux

F:\lua_study\lua-5.1.4\etc>luavs.bat 

(4)src目錄下生成動態庫等等文件,不過我在編譯的時候出現了好多問題,就使用的下面的方法android

2.使用LuaForWindowsios

Lua for Windows 爲 Windows 系統下提供了 Lua 腳本語言的開發和運行環境,不少東西配套好了。nginx

直接像python同樣安裝一下,安裝時把SciTe編輯器也選擇上,像頭文件,庫什麼的都直接放好了。git

推薦這種方法程序員

3.SciTe編輯器

是一個體積小巧的文本編輯器,在安裝LuaForWindows能夠選擇安裝,而且把那個黑底色選擇上更有感受一點。

4.下載地址

http://code.google.com/p/luaforwindows/

或者

http://luaforge.net/frs/?group_id=377

2、Script.Net的IDE環境

藍螞蟻軟件工做室的一個做品,用着感受不錯,用這個也是至關的方便,最主要的是它有vc番茄同樣的提示

下載地址:http://www.blueantstudio.net

先下載 基礎安裝包,再下載安裝Lua開發包

一塊兒學Lua(第二篇-環境搭建) - 熊哥 - 熊哥

3、第一個Lua程序

print("hello lua...")

SciTe編輯器中:

一塊兒學Lua(第二篇-環境搭建) - 熊哥 - 熊哥

4、Lua和VS2008的環境

1.加入外部的頭和庫

VS2008-工具-選項-VC++目錄中,把LuaForWindows安裝下的頭文件和庫文件加到目錄,運行文件在安裝LuaForWindows的時候加入了環境變量,能夠不用加了。
一塊兒學Lua(第二篇-環境搭建) - 熊哥 - 熊哥

2.第一個工程

新建一個vc的命令行工程,寫一個Lua腳本,用C++調用。

腳本:environment_test.lua

function ShowPrint() 
    print( "this is my cpp code call..." ) 
end

C++工程:Lua_c_evn

//註釋:這段代碼是參考網上文章照貓畫虎出來的,只是來驗證環境正確。

  1: //------------------------------------------------- 
  2: //說明:Lua環境測試 
  3: //時間:2011-7-28 
  4: //環境:vs2008 
  5: //------------------------------------------------- 
  6: #include "stdafx.h" 
  7: #include <iostream> 
  8:  
  9: extern "C" { 
 10: #include <lua.h> 
 11: #include <lualib.h> 
 12: #include <lua.hpp> 
 13: } 
 14:  
 15: #pragma comment(lib,"lua5.1.lib")   
 16:  
 17: int _tmain(int argc, _TCHAR* argv[]) 
 18: { 
 19:   lua_State *L = lua_open(); // 
 20:   luaL_openlibs(L); //加載 .lib 文件  
 21:  
 22:   // 加載腳本文件,須要放在程序目錄   
 23:   luaL_loadfile( L, "environment_test.lua" );   
 24:   lua_resume( L, 0 );   
 25:  
 26:   // 調用函數   
 27:   lua_getglobal( L, "ShowPrint" );   
 28:   if( lua_resume( L, 0 ) )   
 29:   { 
 30:     printf( "%s/n", lua_tostring( L, 1) );   
 31:   } 
 32:    
 33:   // 調用結束   
 34:   lua_close(L);   
 35:  
 36:   std::system("pause");   
 37:  
 38:   return 0; 
 39: } 
 40:  
 41: 

直接運行,結果

一塊兒學Lua(第二篇-環境搭建) - 熊哥 - 熊哥

OK,環境配置看來是正確了,以後,就開始真正的Lua之旅了。

5、參考引用

全部文章您均可以任意轉載,修改,演繹,但請保持完整性並留個大媽般的出處,不要誤導他人

本文出處(熊哥)

http://pppboy.blog.163.com/blog/static/30203796201162811730972/

引用申明

http://blog.csdn.net/kingsollyu/article/details/6613468

http://blog.csdn.net/kun1234567/article/details/1929815

http://baike.baidu.com/view/1207529.htm

 

 

生產環境中 Ngx_lua 使用技巧和應用的範例

2013-09-10 17:25:05     發表評論

 

   Rewrite phase.

   Access phase.

   Content phase.

詳細的步驟:

1.init_by_lua  上下文http  ngx啓動時執行
2. set_by_lua  上下文 server, server if, location, location if
3.rewrite_by_lua 上下文  http, server, location, location if
4.access_by_lua 上下文 http, server, location, location if
5.content_by_lua 上下文   location, location if
6.header_filter_by_lua 上下文   http, server, location, location if
7.body_filter_by_lua 上下文 http, server, location, location if
8.log_by_lua 上下文 http, server, location, location if

我們再過濾post、get請求或者是觸發了某個access、rewrite,若是發現惡意和違規的侵入的話,能夠發郵件報警,好讓咱們第一時間收到郵件的信息。

location = /smtp {
        default_type "text/plain";
        content_by_lua '
            local smtp = require("socket.smtp")
            local from = "<ruifengyunceshi@163.com>"
            local  rcpt = {"",}
            local   mesgt = {
            headers = {
            to = "", -- 收件人
            subject = "This is Mail Title"
            },
        body = "This is  Mail Content."
    }
     local  r, e = smtp.send{
        server="smtp.163.com",
        user="",
        password="",
        from = from,
        rcpt = rcpt,
        source = smtp.message(mesgt)
      }
    if not r then
        ngx.say(e)
    else
        ngx.say("send ok!")
    end
    ';
    }

lua這東西挺怪的,他的雙引號和單引號是有很大區別的,我到如今也沒搞明白,啥區別,反正用雙引號就對了。。。有事error.log報錯的話,改爲單引號試試。。

好點的方法是  先在lua的環境中跑一邊,ok後,在放到ngx_lua裏面。

Lua有豐富的接口的方案,不僅是給別人提供的接口,還有他本身訪問別的接口所用的模塊。

若是你的同事那邊已經有個高性能的socket接口,那你就別麻煩他改爲rest模式了。畢竟socket對socket速度很快的。

location /cosocket {
        default_type "text/plain";
        content_by_lua '
        local sock = ngx.socket.tcp()
        sock:settimeout(1000)
        local ok, err = sock:connect("127.0.0.1", 12000)
        if not ok then
            ngx.say("failed to connect: ", err)
            return
        end
        local bytes, err = sock:send("flush_all")
        ngx.say(bytes,err)
        if not bytes then
            ngx.say("failed to send query: ", err)
            return
        end
       local line, err = sock:receive()
        if not line then
            ngx.say("failed to receive a line: ", err)
            return
        end
        ngx.say("result: ", line)
        ';
      }
                                                                                                                                                                                                                                                                                                                                                                                         
    }
}

對於給別人的mysql查詢,給帳號密碼不合適,和一個小權限的帳號密碼也不合適。

這種狀況,咱們要是求高性能的話,能夠用lua配置cjson作成rest接口。

location /select2 {
content_by_lua '
local mysql = require "resty.mysql"
local db,err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ",err)
return
end
db:set_timeout(1000)
local ok,err,errno,sqlstate = db:connect{
host = "127.0.0.1",
port = 3306,
database = "niubi",
user = "ruifengyun",
password = "",
max_package_size = 1024
}
if not ok then
ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate)
return
end
ngx.say("connected to mysql.")
res,err,errno,sqlstate = db:query("select username,password from users where id="..ngx.var.arg_id)
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
local cjson = require "cjson"
ngx.say("result: 「,cjson.encode(res))
';
}

我們既然知道了 lua的強大之處, 能夠從lua裏面搞負載均衡。

往redis裏面 扔兩個key   好比 web1 8.8.8.111  web2 8.8.8.222

server {
  listen 80;
  server_name _;
  server_name_in_redirect off;
  port_in_redirect off;
  root /root/html;
  location / {
    set $upstream "";
    rewrite_by_lua '
      local routes = _G.routes
      -- setup routes cache if empty
      if routes == nil then
        routes = {}
        ngx.log(ngx.ALERT, "Route cache is empty.")
      end
      -- try cached route first      local route = routes[ngx.var.http_host]
      if route == nil then
        local redis  = require "redis"
        local client = redis.connect("localhost", 6379)
        route        = client:get(ngx.var.http_host)
      end
      if route ~= nil then
        ngx.var.upstream = route
        routes[ngx.var.http_host] = route
        _G.routes = routes
      else
        ngx.exit(ngx.HTTP_NOT_FOUND)
      end
    ';
    proxy_buffering             off;
    proxy_set_header            Host $host;
    proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect              off;
    proxy_connect_timeout       10;
    proxy_send_timeout          30;
    proxy_read_timeout          30;
    proxy_pass                  http://$upstream;
  }
}

用lua 對cookie的控制

header_filter_by_lua '
        t = {}
        if ngx.var.http_cookie then
            s = ngx.var.http_cookie
            for k, v in string.gmatch(s, "(%w+)=([%w%/%.=_-]+)") do
                t[k] = v
            end
        end               
        p = ngx.req.get_uri_args()                                                     
        if not t.uid and p.uid then
            expires = ngx.cookie_time(4523969511)
            ngx.header["Set-Cookie"] = {"uid=" .. p.uid .."; expires=" .. expires .. ";
        end
                                                     
';
相關文章
相關標籤/搜索