Freeswitch Lua学习笔记

在FreeSWITCH中,Lua模块是默认加载的。在所有嵌入式脚本语言中,它是最值得推荐的语言。首先它非常轻
量级,mod_lua.so经过减肥(Strip)后只有272KB;另外,它的语法相对的简单。有人做过对比,在嵌入式的脚
本语言里,如果Python得2分,Perl得4分,JavaScript得5,则Lua语言可得10分 [2],由此可见一斑。
另外,Lua模块的文档也是最全的。笔者在使用其他语言(如JavaScript)甚至写Event Socket程序时也经常
参考Lua模块的文档。
注意
FreeSWITCH完全内置了Lua解释器,因此与操作系统上的Lua版本以及各种第三方库一点关系都没有,详细的
配置信息可以参考conf/autoload_configs/lua.conf.xml。
另外,自2013年11月中旬起,FreeSWITCH中的Lua解释器升级到了Lua 5.2版本,因此,读者在写Lua脚本时要
注意使用与Lua 5.2兼容的语法。而原来的Lua模块(基于Lua 5.1)则被移动到了源代码目录下的src/mod/legacy目录
中,如果需要Lua 5.1的用户可以自行编译该版本。
16.2.1 Lua语法简介
Lua的语法非常简洁易懂,有人说:如果你会其他编程语言,则在30分钟内就能学会它 [3]。
大家都知道,如果有某种语言的编程经验,则学一种新的语言时可以对比着学。在这里,我们对比大家比较
熟悉的JavaScript语言 [4]来学习Lua。
1.相似性
Lua与JS(JavaScript的缩写,下同)有很多相似的地方,简述如下。
·变量无需声明。Lua与JS都是“弱”类型的语言(不像C),所以它们不需要事先声明变量的类型。
·区分大小写。Lua和JS都是区分大小写的。true和false分别代表布尔类型的真和假,true与True或TRUE是完
全不同的。
·函数可以接受个数不定的参数。与JS类似,在Lua中,与已经声明的函数参数个数相比,实际传递的参数个
数可多可少,如:
function showem( a, b, c )
print( a, b, c )
end
showem( 'first' ) --> first nil nil
showem( 'first', 'second' ) --> first second nil
showem( 'first', 'second', 'third' ) --> first second third
showem( 'first', 'second', 'third', 'fourth' ) --> first second third
在Lua中,个数不定的参数列表使用“...”(称为vararg expressions)来表示,如:
function showem(a, b, ...)
local output = tostring(a) .. "\t" .. tostring(b)
local theArgs = { ... }
for i,v in ipairs(theArgs) do
output = output .. "\t#" .. i .. ":" .. v
end
print(output)
end
showem('first' ) --> first nil
showem('first', 'second') --> first second
showem('first', 'second', 'third') --> first second #1:third
showem('first', 'second', 'third', 'fourth') --> first second #1:third #2:fourth
·哈希可以用方括号或点方式引用。哈希表是编程语言中一种重要的数据结构。在Lua中,哈希表用Table来
实现,在JS中,用稀疏在数组实现。无论如何,在两者中都可以使用如下的语法引用,如:
theage = gavin['age']
theage = gavin.age
·数字区别不大。在JS和Lua中,整数和浮点数是没有区别是的。它们在内部都是以浮点数表示。在Lua中,
所有的数字类型都是number类型。
·分号是可选的。两者类似,在不产生歧义的情况下,行尾的分号可以有,也可以没有。不同的是对待分号
的方式,在JS中,按惯例是包含分号的,而在Lua中,惯例是不包含分号的。
·默认全局变量。在JS中,如果用var声明一个变量并赋值,则它是本地变量;如果不用var声明,默认就是全
局的,如:
function foo( )
{
var jim = "This variable is local to the foo function";
jam = "This variable is in global scope";
}
而在Lua中也类似,用local声明一个本地变量,省略local时则默认为全局变量:
function foo( )
local jim = "This variable is local to the foo function";
jam = "This variable is in global scope";
end
·使用双引号和单引号表示字符串。在JS和Lua中,字符串是用引号引起来的,并且单引号和双引号的作用没
有任何不同 [5]。引号要配对使用,但这两种引号可以混合以避免使用转义符,必要时可以使用“\”来转义,如
(其中,箭头后面为实际变量的值):
local book = "Seven's Book"; --> Seven's Book
local book = 'Seven\'s Book'; --> Seven's Book
local book = '"Awsome" book of Seven'; --> "Awsome" book of Seven
local book = "\"Awsome\" book of Seven"; --> "Awsome" book of Seven
·函数是一等公民。在JS和Lua中,函数是一等公民,这意味着,你可以将它赋值给一个变量,将它作为参数
传递,或者直接加上括号进行调用,如在Lua中:
1 mytable = { }
2 mytable.squareit = function( x )
3 return x * x
4 end
5 thefunc = mytable.squareit
6 print( thefunc( 7 ) ) --> 49
其中,第1行声明一个Table类型的变量mytable;第2~4行定义一个匿名函数,并将它赋值给mytable的
squareit成员变量;第5行将上述成员变量的值又赋值给了一个变量thefunc。至此,thefunc实际上就代表第2行
至第4行定义的匿名函数。最后,在第6行就可以通过thefunc引用该函数,该函数对输入的参数7进行平方计算
(x*x),最后得到结果49。
·函数都是闭包。在JS和Lua中,函数都是闭包。简单来说,这意味着函数可以随时访问该函数在定义时可以
访问的本地变量,尽管在以后调用时这些本地变量逻辑上已经“失效”了。比如下面的Lua例子中,inBaseValue中
在定义时有效,却能在调用时照样使用它。
function MakeAdder( inBaseValue )
return function( inValueToAdd )
return inBaseValue + inValueToAdd
end
end
add10 = MakeAdder( 10 )
add30 = MakeAdder( 30 )
print( add10( 1 ) ) --> 11
print( add10( 6 ) ) --> 16
print( add30( 3 ) ) --> 33
2.区别
Lua与JS又有很多区别,简述如下:
·单行和多行注释不同。JS使用“//”做单行注释,而Lua使用“--”。JS使用“/*...*/”来做多行注释,而
Lua中使用“--[[...]]”(注意,这里的“...”表示实际被注释的内容)。
JS中多行注释不能嵌套,解析器将在遇到第一个“*/”时终止该注释,而在Lua中,则可以使用类似“--[===
[...]===]”的方式,通过在方括号中多加几个等号(前后等号的数量要匹配)来改变最外层的注释。参考以下
Lua注释:
--
local jim = "This is not commented"
--[[
local foo = "
" "
local bar = "
" "
--]]
local jam = "
" "
---[[
local foo = "
" "
local bar = "
“- “-

--]]
--[==[
--[[
local foo = "foo"
local bar = "bar"
--]]
--]==]
·用end终止程序块。Lua与Ruby类似,使用end来代替JS中的大括号来终止程序块,如下面是Lua中终止程序
块的语法:
function foo( )
--my code here
end
if foo( ) then
--my code here
end
for i=0,1000 do
--my code here
end
·使用nil代表空值。类似Ruby,在Lua中,使用nil代表空值,在JS及C语言中则使用null或NULL。
在JS中,空字符串("")和0在条件测试中都为假(false)。而在Lua中,nil和false是仅有的
非“真”(True)值,其他所有的都表示测试结果为真。

Lua中任何值都可以作为Table的键(Key)。在JS中,对象(Object)的所有键都是字符串(如myObj[11]与
myObj["11"]是相同的),而在Lua中,字符串、数字、甚至另一个Table都可以是键。参见如下Lua代码:
a = {}
b = {}
mytable = {}
mytable[1] = "The number one"
mytable["1"] = "The string one"
mytable[a] = "The empty table 'a'"
mytable[b] = "The empty table 'b'"
print( mytable["1"] ) --> The string one
print( mytable[1] ) --> The number one
print( mytable[b] ) --> The empty table 'b'
print( mytable[a] ) --> The empty table 'a'
·Lua中没有数组,任何复杂的数据类型都是Table。在JS里有明确的数组对象,并且有对应的操作数组的方
法,如:
var myArray = new Array( 10 ); //
10 10
var myArray1 = [ 1, 2, 3 ]; //
3 3
myArray1.pop(); //
而在Lua中,对象是Table、prototype是Table、哈希是Table、数组是Table、Table是Table、什么都是
Table。
Lua中的所谓数组本身是一个Table,它相当于JS里的稀疏数组,只是它的第一个元素的下标是从1开始的,而
不是0。可以使用Table的语法来创建数组。如下面Lua代码中的两种方法是等价的:
people = { "Alice", "Bob", "Carl" }
people = { [1]="Alice", [2]="Bob", [3]="Carl" }
如果拿Table当数组来用,可以使用两种方法来获取和设置数组的大小,并允许数组中有空值存在,如:
people = { "Alice", "Bob", "Carl" }
print( table.getn( people ) ) --> 3
people[ 7 ] = "Someone Else "
print( table.getn( people ) ) --> 3
print( people[ 10 ] ) --> "Some Dude"
for i=1,table.getn( people ) do
print( people[ i ] )
end
--> Alice
--> Bob
--> Carl
table.setn( people, 7 )
print( table.getn( people ) ) --> 7
for i=1,table.getn( people ) do
print( people[ i ] )
end
--> Gavin
--> Stephen
--> Harold
--> nil
--> nil
--> nil
--> Someone Else
·数字、字符串以及Table都不是对象。与面向对象概念里面的对象不同,数字、字符串以及Table本质上都
不是对象。
Lua仍然是面向过程的编程,大多数操作可以通过库函数实现,如:
print(string.len(mystring) ) --> 11
print(string.lower(mystring)) --> hello world
其中,string.len是一个函数,实际上string本身是一个Table。从Lua5.1起,也支持一些类似面向对象的语
法,如上面的例子等价于:
mystring = "Hello World"
print(mystring:len()) --> 11
print(mystring:lower()) --> hello world
在上面的例子中,通过使用“:”,把mystring看成一个对象,然后len和lower就类似于这个对象的方法。便
实际上,Lua是在内部把mystring这个假的“对象”特殊处理了,找到它所对应的数据类型(string)后,调用实
际的string.len(),并把mystring作为该函数的第一个参数,所以mystring:len()与string.len(mystring)是等
价的。
·没有++和+=。在Lua中没有++和+=这样的缩写形式,所以变量自加必须用以下方式:
local i = 0;
i = i + 1;
字符串的拼接是使用“..”操作符实现的,如:
local themessage = "Hello"
themessage = themessage .. " World"
如果把一个字符串和一个数字相加,Lua会试图将字符串转换成数字,如:
print(10 + "2") --> 12
print(10 + "a") -->
attemapttt etmop tp etrof opremr faorrimt hamreittihcm eotni ca osnt rai nsgt rvianlgu evalue
·没有三目运算符。JS或C中的“a?b:c”语法是很贴心的,但在Lua中没有。不过,Lua中有个“短路”语法,
与该功能类似,如:
local foo = (math.random( ) > 0.5) and "It's big!" or "It's small!"
local numusers = 1
print( numusers .. " user" ..
(numusers == 1 and " is" or "s are") .. " online.")
--> 1 user is online.
numusers = 2
print( numusers .. " user" ..
(numusers == 1 and " is" or "s are") .. " online.")
--> 2 users are online.
·模式匹配。正则表达式是很方便的字符串匹配工具。与JS以及其他语言不同,为了保持Lua的小巧且减少对
其他库的依赖,Lua没有使用常用的POSIX(regexp),也没有使用PCRE(Perl兼容的正则表达式),而是自己实现
了模式匹配算法,其语法也有很大不同。
模式(Pattern)实际上就是Lua中的正则表达式。它与普通正则表达式最大的不同就是使用“%”而不是使
用“\”来转义。Lua模式中的字符分类如表16-1所示。
表16-1 Lua中的模式

除此之外,它还有一些具有魔法含义的特殊字符,这些字符有:
( ) . % + - * ? [ ] ^ $
它们的含义都与PCRE里的差不多的,其中“-”的含义与“*”类似,都是重复前一个字符0次或多次,不同的
是,“*”为最大匹配,它会尽量匹配更长的字符串,而“-”为最小匹配,它会尽量匹配更短的字符串。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Freeswitch is an open-source telephony platform that allows you to build various communication applications. It supports multiple scripting languages, including Lua. Lua is a lightweight and powerful scripting language that is often used for extending the functionality of Freeswitch. With Lua, you can write custom applications, create dial plans, handle call control logic, and interact with various telephony features provided by Freeswitch. Lua scripts in Freeswitch are typically used for tasks such as call routing, IVR (Interactive Voice Response) systems, call recording, and more. To use Lua with Freeswitch, you need to have the mod_lua module enabled in your Freeswitch installation. Once enabled, you can start writing Lua scripts to control call flows and handle telephony events. Here is a simple Lua script example for Freeswitch that answers an incoming call and plays a welcome message: ```lua -- answer.lua session:answer() session:streamFile("/path/to/welcome-message.wav") ``` In this example, the `session:answer()` function answers the incoming call, and the `session:streamFile()` function plays an audio file to the caller. You can save this script as `answer.lua` and load it in your Freeswitch dial plan configuration to execute it when an incoming call arrives. Note that this is just a basic example, and Lua with Freeswitch offers much more functionality and flexibility. Feel free to explore the official Freeswitch documentation and Lua scripting resources for more advanced use cases and examples.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值