分类目录学习心得

GoLang学习心得1

最近在学习GoLang,学习这语言的最主要原因——换工作了

由于各种原因,辞去了待了三年的公司,然后又找了一家新的。由于这家规模没有之前那个大,各种福利就跟不上,多少心里有些落差,可这阻碍不了我工作的激情,面对工作,我还是很认真的。

或者是因为“金三银四”的原因,最近感觉跳槽的人很多……(好像我上一次跳槽也是在3月份)进到这个新公司,本来是一web前端为主,可人员变动,之前负责一个代理端的人员跑了,一下子没有人来接手这个项目,结果我就被苦逼的接下了这个项目——用GoLang开发的一个代理。接手的原因是——“我的基础比较扎实”,言外之意,大家都懂的,就好比立马被拉进了一个名叫”这个锅不好接“的聊天群里。说了那么多,结论就是,我换了个公司,然后接了一个用GoLang开发的项目,更直白点说,就是我开始学习GoLang了……

多的不说了,开始进入正题:

面对GoLang,可以说是一脸懵逼。打开百度搜搜,先了解下它到底是啥,然后了解下能干啥,有啥优缺点,一翻搜索后,开始搭建开发环境:

开发环境的搭建就掉进了坑,还好爬的快。网上各种“大神“推荐了好多开发工具:liteide,eclipse……还有好多,出了之前用过eclipse之外,其他都没听过……好吧,那就eclipse……可是,各种弄了后,发现,没法编译程序……或许是我哪里没配置好,还有一个主要原因,是我之前都不喜欢用eclipse,用起来感觉别扭(完全个人原因)。于是还是打开了我的VSCode,搜搜看这万能的”记事本“,能不能进行GoLang的开发。各种试水后,终于搭建起来了,说一下步骤:

1、下载GoLang的环境包,下载地址必须是官网

https://golang.google.cn/dl/

下载下来后,点击安装

2、配置GoLang的环境变量配置

添加GOROOT变量,值为安装的go开发包位置;

如:C:\Go\

添加GOPATH变量,值为你开发go的工作区,就是代码目录,类似java的workspace

如:E:\dev_2019\go

这下命令行中就可以使用go命令,敲击  go env  可查看当前go的环境配置

这个GOPATH很关键,你最好也必须把代码放到这个目录下,而且又讲究:里面会有三个必须目录:

bin\: 可执行文件目录,一般在src下使用go install后,就会生成如windows下的exe文件到这个目录

pkg\: 一些依赖包的目录

src\: 源代码目录,采用go get命令可以安装一些第三方包,然后会放到这个目录下,也会对应生成一个可执行文件到bin下,自己开发的代码也要放到这个目录下,里面的目录结构主要有三个:github.com,golang.org和自己的开发目录,当然,你也可以把自己开发的放到github.com中,然后以自己的github名字区分。

 

一个GoLang的项目,以main函数为入口,编译时候,生成的文件以main函数所在文件夹命名,创建一个简单的hello word后,即可在当前目录下使用go build命令进行编辑,会在当前目录下生成如hello.exe的文件,可以直接运行这个文件则运行你的程序,也可以使用go install命令,把你的程序生成如exe的可执行文件放到GOPATH的bin目录下。

VSCode的开发环境搭建,插件可在VSCode中直接下载,但编译就有些麻烦,需要使用GDB进行编译,一时还没来得及理清这编译环境怎么进行的,我是各种搜索后,就弄好了,等后期有时间了再好好缕缕这编译环境的具体细节。

 

FreeSWITCH核心命令

简介

下面的是根据最新的版本r14778(九月九号)中mod_commands模块提供的命令,这些命令可以使用方式有很多种,如下:

控制台

具体查看下面内容。 译者注:通过FreeSWITCH控制台使用

API/事件 接口

通过API或事件接口调用,如:

  • [[mod_event_socket]]
  • [[mod_xmpp_event]]
  • [[mod_erlang_event]]
  • [[mod_xml_rpc]]

脚本接口

通过脚本进行调用,如下:

  • [[mod_perl]]
  • [[mod_spidermonkey]]
  • [[mod_python]]
  • [[mod_lua]]

拨号方案调用

通过拨号方案进行调用,例子如下:

<source lang="xml">
 <extension name="Make API call from Dialplan">
   <condition field="destination_number" expression="^(999)$">
     <!-- next line calls hupall, so be careful! -->
     <action application="set" data="api_result=${hupall(normal_clearing)}"/>
   </condition>
 </extension>
</source>

其他例子:

<source lang="xml">
 <action application="set" data="api_result=${status()}"/>
 <action application="set" data="api_result=${version()}"/>
 <action application="set" data="api_result=${strftime()}"/>
 <action application="set" data="api_result=${expr(1+1)}"/>
</source>

如果API命令含有多个参数,通常都是以空格隔开。

<source lang="xml">
 <action application="set" data="api_result=${sched_api(+5 none avmd ${uuid} start)}"/>
</source>

API命令依赖于加载的相关模块,从每个模块注册的API命令中都能发现它们的踪影。

想要查看全部API命令列表的话,在cli中输入help或者show api即可。

注:如果你想从拨号方案中调用API命令的话,需要先确认拨号方案自带的dptools里面没有类似的命令。

核心命令

主要在http://fisheye.freeswitch.org/browse/freeswitch.git/src/mod/applications/mod_commands/mod_commands.c中实现。

注:一些状态或列表命令的返回结果默认是以逗号进行分隔的列表。一些模块的返回结果可能也会包含逗号,这样就导致针对结果的自动化处理比较困难。一个解决方法是,是在命令的最后加上“as xml”,这样返回的就是xml格式的结果。

acl

使用acl列表判断ip地址是否为合法访问。

Usage: acl

命令别名alias

别名:一种针对常用命令的快捷输入方式

用法: alias add <别名> <命令> | del [<别名>|*]

例子:

  freeswitch> alias add reloadall reloadacl reloadxml
  +OK
  freeswitch> alias add unreg sofia profile internal flush_inbound_reg
  +OK

别名在重启后需要重设,如果需要重启后仍然生效,需要使用stickyadd参数,如下:

  freeswitch> alias stickyadd reloadall reloadacl reloadxml
  +OK

注:只在mod_console中起作用,在fs_cli中无效。
译者注:mod_console为以前台模式启动的freeswitch的命令输入界面。而fs_cli指的是freeswitch的客户端。

bgapi

用于在线程中执行api命令

用法: bgapi <api命令>[ <参数>]

complete

Complete.

Usage: complete add <word>|del [<word>|*]

译者注:该命令从没用过,不知道干啥的,知道的童鞋,可以来更新该文档。

cond

运算指定的条件,并返回结果。

用法: cond <条件表达式> ? <true val> : <false val>

条件表达式支持的条件有:

== 等于
< 小于
> 大于

例子: 如果第一个值大于第二个,则返回true

 cond 5 > 3 ? true : false
 true

拨号方案中的例子:

   <action application="set" data="voicemail_authorized=${cond(${sip_authorized} == true ? true : false)}"/>

稍复杂的例子:

   <action application="set" data="voicemail_authorized=${cond(${sip_acl_authed_by} == domains ? false : ${cond(${sip_authorized} == true ? true : false)})}"/>

domain_exists

检查指定的domain是否存在:

 用法: domain_exists <domain>

eval

Eval (noop). 计算字符串,扩展通道变量.

用法: eval [uuid:<uuid> ]<expression>

例子:

 eval ${domain}
 10.15.0.94

 eval Hello, World!
 Hello, World!

 eval uuid:e72aff5c-6838-49a8-98fb-84c90ad840d9 ${channel-state}
 CS_EXECUTE

expand

执行变量扩展API。

 用法: [uuid:<uuid> ]<cmd> <args>

例子:

 expand originate sofia/internal/1001%${domain} 9999   

在这个例子中,扩展的变量是${domain}。比如domain的值是192.168.1.1,则扩展后执行的命令为:

 originate sofia/internal/1001%192.168.1.1 9999

fsctl

发送freeswitch控制消息。

 用法: fsctl [send_sighup |
               hupall |
               pause [inbound|outbound] |
               resume [inbound|outbound] |
               shutdown [cancel|elegant|asap|restart] |
               last_sps |
               sps [num] |
               sync_clock |
               sync_clock_when_idle |
               reclaim_mem |
               max_sessions |
               min_dtmf_duration [num] |
               max_dtmf_duration [num] |
               default_dtmf_duration [num] |
               loglevel [level] |
               verbose_events [on|off]
              ]

hupall

用于挂断呼向指定号码的通话。参数为:

clearing_type dialed_ext <extension number>

举个例子来说,杀掉正处于活跃状态、目标号码是1000的通话,命令为:

fsctl hupall normal_clearing dialed_ext 1000

sync_clock

FreeSWITCH不信任系统时间。当系统第一次启动的时候,从系统时间中获取样本时间,然后以此为基准使用单调时钟(monotonic clock)。你可以使用命令“fsctl sync_clock”将FreeSWITCH与系统时间进行同步。

注:该命令会立即生效,会影响CDR里面的时间统计。如会导致计费超前或延后,或者记录的挂断时间小于拨打时间。举个例子来说,如果FS的时钟比系统时间迟一个月,当进行时间同步后,CDR的呼叫记录里面就会出现有的呼叫持续时间为1个月。

命令fsctl sync_clock_when_idle要安全很多,作用和上面一样,但是要到系统中所有通道都空闲的时候才开始时间同步。这种方法不会对CDR产生影响。

sync_clock_when_idle

要到系统没有通话的时候才开始时间同步

sps

该设置会改变swithch.conf文件中设置的sessions-per-second(每秒并发通话数)属性限制

last_sps

查询显示目前生效的sessions-per-second属性。

pause

可以使用参数inbound或outbound来暂停创建呼入或呼出通话,如果没有指定参数的话,则呼入呼出都暂停。resume的用法类似。

min_dtmf_duration

例子:

fsctl min_dtmf_duration 800

译者注:没看懂,就不翻译出来误导人了!
This example sets the min_dtmf_duration switch parameter to 100ms. The number is in clock ticks where clockticks / 8 = ms. The min_dtmf_duration specifies the minimum DTMF duration to use on outgoing events. Events shorter than this will be increased in duration to match min_dtmf_duration. You cannot configure a DTMF duration on a profile that is less than this setting. You may increase this value, but cannot set it lower than 400 (the default). This value cannot exceed max_dtmf_duration. This setting can be changed in switch.conf.xml.

It is worth noting that many devices squelch in-band DTMF when sending RFC 2833. Devices that squelch in-band DTMF have a certain reaction time and clamping time which can sometimes reach as high as 40ms, though most can do it in less than 20ms. As the shortness of your DTMF event duration approaches this clamping threshold, the risk of your DTMF being ignored as a squelched event increases. If your call is always IP-IP the entire route, this is likely not a concern. However, when your call is sent to the PSTN, the RFC 2833 must be encoded in the audio stream. This means that other devices down the line (possibly a PBX or IVR you are calling into) might start considering your DTMF event a squelched tone and ignore it entirely. For this reason, it is recommended that you do not send DTMF events shorter than 80ms.

Checking the current value:

fsctl min_dtmf_duration 0

The code recognizes a duration of 0 as a status check. Instead of setting the value to 0, it simply returns the current value.

====max_dtmf_duration====

Example:

fsctl max_dtmf_duration 80000

This example sets the max_dtmf_duration switch parameter to 10,000ms (10 seconds). The number is in clock ticks (CT) where CT / 8 = ms. The max_dtmf_duration caps the playout of a DTMF event at the specified duration. Events exceeding this duration will be truncated to this duration. You cannot configure a duration on a profile that exceeds this setting. This setting can be lowered, but cannot exceed 192000 (the default). This setting cannot be set lower than min_dtmf_duration. This setting can be changed in switch.conf.xml.

Checking the current value:

fsctl max_dtmf_duration 0

The code recognizes a duration of 0 as a status check. Instead of setting the value to 0, it simply returns the current value.

====default_dtmf_duration====

Example:

fsctl default_dtmf_duration 2000

This example sets the default_dtmf_duration switch parameter to 250ms. The number is in clock ticks (CT) where CT / 8 = ms. The default_dtmf_duration specifies the DTMF duration to use on originated DTMF events or on events that are received without a duration specified. This value can be increased or lowered. This value is lower-bounded by min_dtmf_duration and upper-bounded by max_dtmf_duration. This setting can be changed in switch.conf.xml.

Checking the current value:

fsctl default_dtmf_duration 0

The code recognizes a duration of 0 as a status check. Instead of setting the value to 0, it simply returns the current value.

====verbose_events==== Enables verbose events. Verbose events have ”’every”’ channel variable in ”’every”’ event for a particular channel. Non-verbose events have only the pre-selected channel variables in the event headers. * This setting can also be set in [[switch.conf.xml]].

global_getvar

获取全局变量的值。如果没有提供参数,则返回所有全局变量的值。

用法: global_getvar <varname>

global_setvar

设置全局变量

用法: global_setvar <varname>=<value>

例子:

global_setvar foo=bar

group_call

返回组呼bridge字符串,组呼定义请参考[[XML User Directory Guide#Groups|call group]]。

Usage: group_call group@domain[+F][+A][+E]

+F将会以串行呼叫模式返回组成员(以“|”隔开各成员). +A将会以并行呼叫模式返回组成员(以“,”隔开各成员). +E将会议呼叫模式返回组成员(以:_:隔开各成员),关于企业呼叫请参考[[Freeswitch_IVR_Originate#Enterprise_originate|enterprise fashion]].

请注意:如果你需要设置在外呼通道上面设置用户变量,需要确保你的domain或被拨打组的变量列表里面没有设置dial-string和group-dial-string,用设置用户默认组里面的dial-string和group-dial-string来替代。这样的话,group_call将会返回user/101,user/将会设置你的外呼通道变量。

help

显示所有API命令的帮助信息。

用法: help

host_lookup

针对指定域名做主机查询(host lookup)。

用法: host_lookup <hostname>

hupall

断开现存通话。

用法: hupall <cause> [<variable> <value>]

挂断所有含有变量,并且值为的通话,挂机原因为。

例子:

originate {foo=bar}sofia/internal/someone1@server.com,sofia/internal/someone2@server.com &park

hupall normal_clearing foo bar

in_group

判断用户是否在指定的组中

用法: in_group <user>[@<domain>] <group_name>

is_lan_addr

判断IP是否为内网地址

用法: is_lan_addr <ip>

load

加载外部模块

用法: load <mod_name>

md5

返回指定数据的MD5值。

用法: md5 <data>

module_exists

检查模块是否存在。

用法: module_exists <module>

msleep

休眠指定毫秒

用法: msleep <休眠的毫秒数>

nat_map

用法: nat_map [status|reinit|republish] | [add|del] <port> [tcp|udp] [sticky] | [mapping] <enable|disable>
  • status – 用于显示NAT类型、外网IP(the external IP)以及当前映射的端口。
  • reinit – 重新初始化NAT模块。当你更换路由器或将路由器由NAT切换到UPnP模式的时候,使用该参数。
  • republish – 该参数会让FreeSWITCH重新(向路由器等)发布NAT映射信息。 正常情况下,没有必要使用该参数。
  • mapping – 该参数用于控制是否向NAT设备发送端口映射请求(可使用-nonatmap参数在系统启动时关闭该功能). 之所以存在该参数,是因为有可能需要通过NAT获取公网IP地址,而不需要通过NAT开启端口。

Note: sticky参数用于将映射信息固化下来,在下次FreeSWITCH重启后映射仍然生效。

警告: 如果你有多个网卡,并分别配置了使用相同端口的sip profiles。nat_map在映射端口的时候,会被弄昏头的,不需要将端口映射到哪个sip profile上面,千万别干这种挫事!

regex

执行正则表达式匹配。该参数会根据是否提供参数而实现不同的功能,如下:

  • 如果没提供该参数, ”regex” 将会执行正常的匹配,返回true或者false。
  • 如果提供该参数,如果匹配成功的话,会返回指定的子串。如果匹配失败,则返回全部源字符串。

默认的正则表达式分界符是|(管道符)。可以更改为~或者/,只要在字符串的前面加上’m:’。

Usage: regex <data>|<pattern>[|<subst string>]
       regex m:/<data>/<pattern>[/<subst string>]
       regex m:~<data>~<pattern>[~<subst string>]

例子:

 regex test1234|\d                  <== Returns "true"
 regex m:/test1234/\d               <== Returns "true"
 regex m:~test1234~\d               <== Returns "true"
 regex test|\d                      <== Returns "false"
 regex test1234|(\d+)|$1            <== Returns "1234"
 regex sip:foo@bar.baz|^sip:(.*)|$1 <== Returns "foo@bar.baz"
 regex testingonetwo|(\d+)|$1       <== Returns "testingonetwo" (no match)
 regex m:~30~/^(10|20|40)$/~$1      <== Returns "30" (no match)
 regex m:~30~/^(10|20|40)$/~$1~n    <== Returns "" (no match)
 regex m:~30~/^(10|20|40)$/~$1~b    <== Returns "false" (no match)

版本14727中的逻辑是,如果源字符串匹配匹配到结果,那么条件为false,但是这里仍有一个匹配结果,结果是1001。(这里的翻译是照字面翻译,小伙伴们,你们看懂了没?)
Logic in revision 14727 if the source string matches the result then the condition was false however there was a match and it is 1001.

regex 1001|(^\d{4}$)|$1
  • See also [[Regular_Expression]]

reload

重新加载模块。

用法: reload [-f] <mod_name>

reloadacl

重新加载ACL规则。

用法: reloadacl [reloadxml]

reloadxml

重新加载conf/freeswitch.xml的配置信息到内存中。

用法: reloadxml

show

输出多种(模块)状态报告。

 用法: show <item>
  item类型如下:
  codec
  endpoint
  application
  api
  dialplan
  file
  timer
  calls [count]
  channels [count|like <match string>]
  calls
  detailed_calls
  bridged_calls
  detailed_bridged_calls
  aliases
  complete
  chat
  management
  modules
  nat_map
  say
  interfaces
  interface_types
  tasks
  limits

XML格式输出: show foo as xml

修改输出分隔符: show foo as delim |

  • codec – 列出所有编码
  • endpoint – 列出所有endpoint类型模块
  • application – 列出所有应用程序
  • api – 列出所有api
  • dialplan – 列出拨号方案涉及的模块
  • file – 列出所有支持的文件类型
  • timer – 列出计时器timer模块
  • calls – 列出当前的通话[count]
  • channels – 列出当前的通道 [count|like ]
    注:关于calls与channels的对比,请参考Channels vs Calls
  • bridged_calls – 和”show calls”相同
  • detailed_calls – 和”show calls”类似,但是显示字段更多
  • detailed_bridged_calls – 和”show calls”类似,但是显示字段更多
  • aliases – 列出所有别名(别名干啥用的,暂时未查到)
  • complete – list command complete tables
  • chat – 列出所有chat模块,包括api、sms、conf等
  • management – list management?
  • modules – 列出所有模块
  • nat_map – 列出地址映射表
  • say – 列出有支持语言的say模块
  • interfaces – 列出所有接口
  • interface_types – 列出所有接口类型
  • tasks – 列出任务
  • registrations – 列出所有注册用户

Tips For Showing Calls and Channels

理解show calls/channels真义的最好方式是亲自去尝试。最近(2011.9)又在show命令家族中添加了几位:

  • show detailed_calls
  • show bridged_calls
  • show detailed_bridged_calls

这三个命令用于取代简单的”show calls”。
需要注意的是,”show detailed_calls”取代的是”show distinct_channels”。命令都是相似的,但是返回信息更多。
同样需要注意的是,这里并没有”show detailed_channels”命令,但是使用”show detailed_calls”会让你得到相同的结果。该命令能让你得到“单腿通话”(one-legged calls)或桥接后的通话信息,所以,少年,习惯这条新命令吧!

小贴士2: 有时,你需要获取某个特定的uuid,可以使用下面的方式。
假设你设置了通道变量presence_data,那可以使用下面的命令搜索符合条件的通道(即含有foo的通道): show channels like foo

like将会搜索下面的关键字段:

  • uuid
  • channel name
  • caller id name
  • caller id number
  • presence_data

注: presence_data 必须在bridgeoriginate期间设置,而不是在通道已经建立完成后才设置。

shutdown

停止FreeSWITCH程序。该命令只在cli中起作用,如果想作为api进行调用,需要使用fsctl shutdown

警告!在cli中运行shutdown会忽略掉参数,并立即退出!

用法: fsctl shutdown [cancel|elegant|asap|restart|now] 
  • cancel – 终止上一次提交的shutdown请求
  • elegant – 等待所有通话都停止后才关闭,允许新发起通话.
  • asap – 等待所有通话都停止后才关闭, 不再允许新通话.
  • restart – 在执行完“shutdown”后立即重启FreeSWITCH。
  • now – 立即重启FreeSWITCH。

当使用”elegant”, “asap”或者”now”参数后,还可以后跟restart命令,如下:

用法: fsctl shutdown [elegant|asap|now] restart

status

显示当前FreeSWITCH的运行状态

 用法: status

 freeswitch@internal> status
 UP 0 years, 0 days, 1 hour, 28 minutes, 4 seconds, 208 milliseconds, 305 microseconds
 FreeSWITCH is ready
 4 session(s) since startup
 0 session(s) 0/30                        <- 每秒创建的最大通话数 .. 来自switch.conf.xml
 1000 session(s) max                      <- 同时并存的最大通话数 .. 来自switch.conf.xml
 min idle cpu 0.00/100.00                 <- 达到拒接电话标准的最小闲置CPU值 .. 来自switch.conf.xml (如果该值被启动的话).

strftime_tz

根据不同的时区,显示格式化后的时间。需要查看linux时区标准列表的,请查看/usr/share/zoneinfo/zone.tab。

用法: strftime_tz <timezone> [format_string]

示例: strftime_tz US/Eastern %Y-%m-%d %T

unload

卸载外部模块

用法: unload [-f] <mod_name>

version

显示FreeSWITCH的版本号

用法: version [short]

xml_locate

xml_locate root: 返回FreeSWITCH使用的所有XML
xml_locate <section>: 返回指定<section>的XML

xml_locate directory
xml_locate configuration
xml_locate dialplan
xml_locate phrases

用法: xml_locate [root | <section> | <section> <tag> <tag_attr_name> <tag_attr_val>]

示例: xml_locate directory domain name example.com

xml_wrap

使用xml来包装API命令

用法: xml_wrap <command> <args>

呼叫管理命令

break

被废弃,请查看uuid_break命令

create_uuid

创建一个新的UUID,并以字符串的形式返回。

用法: create_uuid

originate

发起一个新的呼叫

Usage: originate <call_url> <exten>|&<application_name>(<app_args>) 
[<dialplan>] [<context>] [<cid_name>] [<cid_num>] [<timeout_sec>]

参数:

  • <call_url> 呼叫目标URL.
    想多了解sofia sip URL语法的童鞋可以参考: [[Sofia|FreeSwitch Endpoint Sofia]]
  • 目标有如下几类:
    • 进入拨号方案进行路由的目标号码
    • &<application_name>(<app_args>)
      • “&” 表明后面跟的是应用名称,不是一个目标号码
      • (<app_args>) 可选参数 (不是所有应用都需要传递参数,比如park)
      • 下面是可以用在’&’后面的应用列表:
        park, bridge, javascript/lua/perl, playback (移除mod_native_file), and many others.
      • 注1: 用单引号传递含有空格的参数,如’&lua(test.lua arg1 arg2)’
      • 注2: 在&和application_name之间不能含有空格
  • 默认为’XML’,如果没有特别指定的话。
  • 默认为’default’,如果没有特别指定的话。
  • 主叫名称.
  • 主叫号码.
  • 超时时长(单位为秒).

可选参数:
这些可选参数使用大括号包裹,如:

originate {ignore\_early_media=true}sofia/example/user 8334

参数需要使用逗号隔开,例子如下:

originate {ignore_early_media=true,originate_timeout=2}sofia/example/user 8334
  • group_confirm_key
  • group_confirm_file
  • forked_dial
  • fail_on_single_reject
  • ignore_early_media
  • return_ring_ready
  • originate_retries
  • originate_retry_sleep_ms
  • origination_caller_id_name
  • origination_caller_id_number
  • originate_timeout
  • sip_auto_answer

更多变量,参考下面的地址:
[[Channel_Variables#Originate_related_variables|Description of originate’s related variables]]

例子:
假设,你想拨打一个本地注册的sip终端,号码为300,然后执行park操作,如下:
(注:本例中用的sip profile是example,你在实际测试的时候,需要改成你本地电话注册的sip profile,一般为internal)

originate sofia/example/300%pbx.internal &park()

又或者,你想将远程注册的sip终端连到拨号规则8600上

originate sofia/example/300@foo.com 8600

再或者,你想将远程注册的sip终端连到另一个远程终端

originate sofia/example/300@foo.com &bridge(sofia/example/400@bar.com)

还或者, 你甚至可以在接通后执行javascript脚本test.js

originate sofia/example/1000@somewhere.com &javascript(test.js)

如果运行的javascript脚本需要传递参数,则需要使用单引号括起来。

originate sofia/example/1000@somewhere.com '&javascript(test.js myArg1 myArg2)'

在发起呼叫前,设置通道变量

originate {ignore_early_media=true}sofia/mydomain.com/18005551212@1.2.3.4 15555551212

在发起呼叫期间,设置通道变量,并传递给另一个FS

originate {sip_h_X-varA=111,sip_h_X-varB=222}sofia/mydomain.com/18005551212@1.2.3.4 15555551212

注: 你可以设置任何类型的通道变量,即使是自定义变量。如果变量的值含有空格或逗号等符号,使用单引号括起来即可。

originate {my_own_var=my_value}sofia/mydomain.com/that.ext@1.2.3.4 15555551212
originate {my_own_var='my value'}sofia/mydomain.com/that.ext@1.2.3.4 15555551212

如果你想自造一段回铃音给被呼叫方听,try this:

originate {ringback=\'%(2000,4000,440.0,480.0)\'}sofia/example/300@foo.com &bridge(sofia/example/400@bar.com)

如果你想发起呼叫后,通道进入”Ring-Ready”状态后就立即返回,try this:

originate {return_ring_ready=true}sofia/gateway/someprovider/919246461929 &socket(127.0.0.1:8082 async full)

更多信息请查阅return ring ready

你可以将保持等待音乐设置为回铃音,if you want:

originate {ringback=\'/path/to/music.wav\'}sofia/gateway/name/number &bridge(sofia/gateway/name/othernumber)

你可以在后台发起一个呼叫(异步模式),播放一段60秒的提示消息:

bgapi originate {ignore_early_media=true,originate_timeout=60}sofia/gateway/name/number &playback(message)

你可以指定被呼叫方的UUID,只需要下面几步:

  • 使用create_uuid创建一个UUID,待用。
  • 使用uuid_kill直接可以在对方未接听前杀掉该次呼叫。
  • 使用origination_uuid指定uuid之后,被叫方会在整个通话的生命周期中使用该UUID。 * originate {origination_uuid=…}user/100@domain.name.com

下面例子作用:发起一个到外部sip服务器echo conference的呼叫,然后转接到本地用户分机上

originate sofia/internal/9996@conference.freeswitch.org &bridge(user/105@default)

下面例子作用:向’default’以外的context上的分机发起呼叫(FreePBX会用到该特性,如context名字为context_1,context_2等等)

originate sofia/internal/2001@foo.com 3001 xml context_3

如果你想对多个分机发起呼叫,可以使用下面的命令:

originate user/1001,user/1002,user/1003 &park()

如果需要在收到early media的时候,将外呼的电话转入会议中,可以使用下面的两个命令,作用一样

originate sofia/example/300@foo.com &conference(conf_uuid-TEST_CON)
originate sofia/example/300@foo.com conference:conf_uuid-TEST_CON inline

   ( See [[Misc._Dialplan_Tools_InlineDialplan]] for more detail on 'inline' Dialplans )

下面的例子演示如何在A-leg上面使用loopback和inline
我是例子

pause

停止指定通道的媒体播放

用法: pause <uuid> <on|off>

uuid_answer

应答

用法: uuid_answer <uuid>
  • See Also: [[Misc.Dialplan_Tools_answer]]

uuid_audio

调整信道上面的音量,或直接通过一个媒体bug进行静音(读/写)

用法: uuid_audio <uuid> [start [read|write] [mute|level <level>]|stop]

level的值范围从-4到4,默认值为0。

uuid_break

断开发送至指定信道的媒体流。举例来说,如果此时正在信道上面播放一个音频文件,使用uuid_break命令,就会断开媒体,呼叫会顺着拨号方案、脚本等往下执行。

用法: uuid_break <uuid> [all]

如果使用all标记的话,所有信道上面正在排队等待播放的音频文件都会被移除,但是如果没有all标记的话,只有当前正在播放的音频文件会被断开。

uuid_bridge

桥接两条呼叫的腿。

Usage: uuid_bridge <uuid> <other_uuid>

uuid_bridge至少需要有一条腿是被呼通的。

uuid_broadcast

在一个指定UUID的信道上执行任意一个拨号方案程序。如果指定了某录音文件名,则代表将会在该信道上播放该文件。 执行拨号方案程序的语法规则是“app::args”。

用法: uuid_broadcast <uuid> <path> [aleg|bleg|both]

在选定的腿上执行应用程序,执行完毕后挂断,并指明挂机原因。

用法: uuid_broadcast <uuid> app[![hangup_cause]]::args [aleg|bleg|both]

具体应用举例如下:

 uuid_broadcast 336889f2-1868-11de-81a9-3f4acc8e505e sorry.wav both
 uuid_broadcast 336889f2-1868-11de-81a9-3f4acc8e505e say::en\snumber\spronounced\s12345 aleg
 uuid_broadcast 336889f2-1868-11de-81a9-3f4acc8e505e say!::en\snumber\spronounced\s12345 aleg
 uuid_broadcast 336889f2-1868-11de-81a9-3f4acc8e505e say!user_busy::en\snumber\spronounced\s12345 aleg
 uuid_broadcast 336889f2-1868-11de-81a9-3f4acc8e505e playback!user_busy::sorry.wav aleg

uuid_buglist

列出信道上面的媒体bug(media bugs)

用法: uuid_buglist <uuid>

uuid_chat

发送聊天信息

用法: <uuid> <text>

如果和会话(session,由uuid指定)相关的终端有一个receive_event handler,该消息会被发往终端,并以及时消息的形式显示出来。

uuid_debug_media

该命令过去为uuid_debug_audio,但是因为加入了一些视频的内容,所以改为现在的名字。

调试媒体流

用法:

<uuid> <read|write|both|vread|vwrite|vboth> <on|off>

使用“read”、“write”或者“both”(同时调试两个方向)作为语音流的方向,以进行调试。 在前面加上“v”,代表视频流的调试。

Read Format

“R %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u m=%d\n”

where the values are:

* switch_channel_get_name(switch_core_session_get_channel(session)),
* (long) bytes,
* my_host, switch_sockaddr_get_port(rtp_session->local_addr),
* old_host, rtp_session->remote_port,
* tx_host, switch_sockaddr_get_port(rtp_session->from_addr),
* rtp_session->recv_msg.header.pt, 
* ntohl(rtp_session->recv_msg.header.ts), 
* rtp_session->recv_msg.header.m

Write Format

“W %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u m=%d\n”

where the values are:

* switch_channel_get_name(switch_core_session_get_channel(session)),
* (long) bytes,
* my_host, switch_sockaddr_get_port(rtp_session->local_addr),
* old_host, rtp_session->remote_port,
* tx_host, switch_sockaddr_get_port(rtp_session->from_addr),
* send_msg->header.pt, 
* ntohl(send_msg->header.ts), 
* send_msg->header.m);

uuid_deflect

通过发送REFER方法,将当前FreeSWITCH上面的某个已经应答的sip呼叫转移走。

用法: uuid_deflect <uuid> <sip URL>

在命令执行后,uuid_deflect等待远端的应答,以此判断转移是否成功。远端返回的sip内容(sip fragment)将会作为uuid_deflect命令的返回结果。如果远端报告REFER成功,FreeSWITCH将会向那条信道发送bye信令。

举例如下:

uuid_deflect 0c9520c4-58e7-40c4-b7e3-819d72a98614 sip:info@example.net

返回内容:

Content-Type: api/response
Content-Length: 30

+OK:SIP/2.0 486 Busy Here

uuid_displace

将目标信道上面的语音流替换为指定的录音(文件)。

参数:

* uuid = 通话的唯一标识符(通过“show channels"可查看到)
* start|stop = 启动/停止该操作
* file = 要播放的语音源(wav,shout等等)路径
* limit = 语音替换(文件)的最大播放时长,秒数
* mux = 该选项将会导致原始的语音流与录音(文件)进行混音。比如,你在替换语音的时候,仍想与另一端进行会话(即在听到替换的录音文件的时候,也能听到对方的声音)。

用法:

uuid_displace <uuid> [start|stop] <file> [<limit>] [mux]

举例如下:

uuid_displace 1a152be6-2359-11dc-8f1e-4d36f239dfb5 start /sounds/test.wav 60
uuid_displace 1a152be6-2359-11dc-8f1e-4d36f239dfb5 stop /sounds/test.wav

uuid_display

更新话机的显示内容,前提是话机支持该功能。目前有Polycom和Snom等部分Sip话机支持该功能。

用法: <uuid> [<display>]

该命令会导致重新协商语音编码。SIP->RTP包的大小应该是0.020。如果在SPA系统话机上,设置为0.030的话,会引起DTMF延迟(DTMF lag)。当话机上的按键被按下的时候,我们可以通过fs_cli看到,但是会有4到6秒的延迟。

uuid_dual_transfer

将处于通话中的双方分别转移到不同的目的地。

-USAGE: <uuid> <A-dest-exten>[/<A-dialplan>][/<A-context>] <B-dest-exten>[/<B-dialplan>][/<B-context>]

uuid_dump

导出指定会话中的所有变量

Usage: uuid_dump <uuid> [format]

导出格式: XML

uuid_early_ok

停止忽略早期媒体(即正常播放early media)。 如果此时ignore_early_media=true,该命令将会停止忽略早期媒体(让参数ignore_early_media设置不起作用),并正常播放。

用法: uuid_early_ok

uuid_exists

检查给定的uuid是否存在。

用法: uuid_exists

uuid_flush_dtmf

刷新DTMF数字缓存,将在排队的DTMF全部送出

Usage: uuid_flush_dtmf

uuid_fileman

管理正在信道中播放的音频流,该音频来自一个语音文件。

用法: uuid_fileman <cmd:val>

命令如下:

*speed:<+[step]>|<-[step]>    语速
*volume:<+[step]>|<-[step]>   音量
*pause                         暂停
*stop                          停止
*truncate                      截断
*restart                      重启
*seek:<+[samples]>|<-[samples]> 定位

Samples,从字面上来讲,就是语音文件前进后退的取样数。在8KHZ的文件中,取样数8000代表的是一秒。同样,在16KHZ的文件中,16000代表的也是一秒。

uuid_getvar

获取指定的信道变量

用法: uuid_getvar

uuid_hold

保持通话

用法:

uuid_hold <uuid>           保持通话
uuid_hold off <uuid>       结束保持,恢复正常通话
uuid_hold toggle <uuid>    在保持和取消保持间切换

uuid_kill

重置(杀掉)指定的信道

用法: uuid_kill [cause]

uuid_limit

Apply or change limit(s) on a specified uuid.

Usage: uuid_limit [[/interval]] [number [dialplan [context]]]

See also [[Limit]]

uuid_media

Reinvite FreeSWITCH out of the media path:

Usage: uuid_media [off]

Reinvite FreeSWITCH back in:

Usage: uuid_media

uuid_media_reneg

API command to tell a channel to send a re-invite with optional list of new codecs

Usage: uuid_media_reneg

uuid_park

Park call

Usage: uuid_park

uuid_preanswer

Preanswer a channel.

Usage: uuid_preanswer

  • See Also: [[Misc._Dialplan_Tools_pre_answer]]

uuid_preprocess

Pre-process Channel

Usage: uuid_preprocess <>

uuid_recv_dtmf

Send DTMF digits to set.

Usage: uuid_recv_dtmf [@]

Use the character w for a .5 second delay and the character W for a 1 second delay.

Default tone duration is 2000ms .

uuid_send_dtmf

Send DTMF digits.

Usage: uuid_send_dtmf [@]

Use the character w for a .5 second delay and the character W for a 1 second delay.

Default tone duration is 2000ms .

uuid_send_info

Send info to the endpoint

Usage: uuid_send_info

uuid_session_heartbeat

Usage: uuid_session_heartbeat [sched] [0|]

uuid_setvar

Set a variable on a channel. If value is omitted, the variable is unset.

Usage: uuid_setvar [value]

uuid_setvar_multi

Set multiple vars on a channel.

Usage: uuid_setvar_multi =[;=[;…]]

uuid_simplify

This command directs FreeSWITCH to remove itself from the SIP signaling path if it can safely do so

Usage:

uuid_simplify

uuid_transfer

Transfers an existing call to a specific extension within a and . Dialplan may be “xml” or “directory”.

Usage:

uuid_transfer [-bleg|-both] [] []

The optional first argument will allow you to transfer both parties (-both) or only the party to whom is talking.(-bleg)

NOTE: if the call has been bridged, and you want to transfer either sides of the call, then you will need to use (or the API equivalent). If it’s not set, transfer doesn’t really work as you’d expect, and leaves calls in limbo.

Record/Playback Commands

uuid_record

Record the audio associated with the given UUID into a file. The start command causes FreeSWITCH to start mixing all call legs together and saves the result as a file in the format that the file’s extension dictates. (if available) The stop command will stop the recording and close the file. If media setup hasn’t yet happened, the file will contain silent audio until media is available. Audio will be recorded for calls that are parked. The recording will continue through the bridged call. If the call is set to return to park after the bridge, the bug will remain on the call, but no audio is recorded until the call is bridged again. (TODO: What if media doesn’t flow through FreeSWITCH? Will it re-INVITE first? Or do we just not get the audio in that case?)

Usage:

uuid_record [start|stop] []

Where limit is the max number of seconds to record.

If the path is not specified on start it will default to the channel variable “sound_prefix” or FreeSWITCH base_dir when the “sound_prefix” is empty.

You may also specify “all” for path when stop is used to remove all for this uuid

“stop” command must be followed by option.

[[Channel_Variables#Call_Recording_Related|See record’s related variables]]

Limit Commands

[[Limit#API|limit_reset]]

Reset a limit backend.

[[Limit#API|limit_status]]

Retrieve status from a limit backend.

[[Limit#API|limit_usage]]

Retrieve usage for a given resource.

[[Limit#API|uuid_limit_release]]

Manually decrease a resource usage by one.

[[Limit#API|limit_interval_reset]]

Reset the interval counter to zero prior to the start of the next interval.

Misc. Commands

bg_system

Execute a system command in the background.

Usage: bg_system

echo

Echo input back to the console echo This text will appear This text will appear

file_exists

Tests whether ”filename” exists.

file_exists filename

Examples:

file_exists /tmp/real_file true file_exists /tmp/missing_file false

Example dialplan usage:

 <extension name="play-news-announcements">
   <condition expression="${file_exists(${sounds_dir}/news.wav)}" expression="true"/>
     <action application="playback" data="${sounds_dir}/news.wav"/>
     <anti-action application="playback" data="${soufnds_dir}/no-news-is-good-news.wav"/>
   </condition>
 </extension>

”’Note”’ this tests whether FreeSWITCH can see the file, but the file may still be unreadable (permissions).

find_user_xml

Checks to see if a user exists; Matches user tags found in the directory, similar to [[user_exists]], but returns an XML representation of the user as defined in the directory (like the one shown in [[Mod_commands#user_exists|user_exists]]).

Usage: find_user_xml

Where key references a key specified in a directory’s user tag, user represents the value of the key, and the domain is the domain the user is assigned to.

list_users

Lists Users configured in Directory

Usage: list_users [group ] [domain ] [user ] [context ]

Example:

freeswitch@localhost> list_users group default

userid|context|domain|group|contact|callgroup|effective_caller_id_name|effective_caller_id_number
2000|default|192.168.20.73|default|sofia/internal/sip:2000@192.168.20.219:5060|techsupport|B#-Test 2000|2000
2001|default|192.168.20.73|default|sofia/internal/sip:2001@192.168.20.150:63412;rinstance=8e2c8b86809acf2a|techsupport|Test 2001|2001
2002|default|192.168.20.73|default|error/user_not_registered|techsupport|Test 2002|2002
2003|default|192.168.20.73|default|sofia/internal/sip:2003@192.168.20.149:5060|techsupport|Test 2003|2003
2004|default|192.168.20.73|default|error/user_not_registered|techsupport|Test 2004|2004

+OK

Search items can be combined:

freeswitch@localhost> list_users group default user 2004

userid|context|domain|group|contact|callgroup|effective_caller_id_name|effective_caller_id_number
2004|default|192.168.20.73|default|error/user_not_registered|techsupport|Test 2004|2004

+OK

sched_api

Schedule an API call in the future. Usage: sched_api [+@]

time is the UNIX timestamp at which the command should be executed. If it is prefixed by +, 

Scheduled task or group of tasks can be revoked with sched_del or unsched_api.

You could put “&” symbol at the end of the line to make command to be executed in its own thread.

Example: sched_api +1800 none originate sofia/internal/1000%${sip_profile} &echo() sched_api @600 check_sched log Periodic task is running…

sched_broadcast

Play a file to a specific call in the future. Usage: sched_broadcast [+]

Schedule execution of an application on a chosen leg(s) with optional hangup: Usage: sched_broadcast [+]

time is the UNIX timestamp at which the command should be executed (or if it is prefixed by +, the number of seconds to wait before executing the command)

Example: sched_broadcast +60 336889f2-1868-11de-81a9-3f4acc8e505e commercial.wav both sched_broadcast +60 336889f2-1868-11de-81a9-3f4acc8e505e say::en\snumber\spronounced\s12345 aleg

sched_del

Removes a prior scheduled group or task ID Usage: sched_del <group_name|task_id>

The one argument can either be a group of prior scheduled tasks or the returned task-id from sched_api.

Example: sched_del my_group sched_del 2

sched_hangup

Schedule a running call to hangup.

Usage: sched_hangup [+]

Note: sched_hangup +0 is the same as uuid_kill

sched_transfer

Schedule a transfer for a running call.

Usage: sched_transfer [+]

stun

Executes a STUN lookup. Usage: stun [:port]

Example: stun stun.freeswitch.org

system

Execute a system command.

Usage: system

The command is passed to the system shell, where it may be expanded or interpreted in ways you don’t expect. This can lead to security bugs if you’re not careful. For example, the following command is dangerous:

If a malicious remote caller somehow sets their caller ID name to “; rm -rf /”, you would unintentionally be executing this shell command:

log_caller_name; rm -rf /

time_test

Time test.

Usage: time_test [count]

Runs a test to see how bad timer jitter is. It runs the test count times (default 10) and tries to sleep for mss microseconds. It returns the actual timer duration along with an average.

Sample:

time_test 100 5

test 1 sleep 100 99
test 2 sleep 100 97
test 3 sleep 100 96
test 4 sleep 100 97
test 5 sleep 100 102
avg 98

timer_test

Timer test.

Usage: timer_test <10|20|40|60|120> [<1..200>] []

Runs a test to see how bad timer jitter is. Unlike time_test, this uses the actual freeswitch timer infrastructure to do the timer test and exercises the timers used for call processing.

First argument is the timer interval. Second is the count. Third is the timer name (“show timers” will give you a list)

Example:

timer_test 20 3

Avg: 16.408ms Total Time: 49.269ms

2010-01-29 12:01:15.504280 [CONSOLE] mod_commands.c:310 Timer Test: 1 sleep 20 9254
2010-01-29 12:01:15.524351 [CONSOLE] mod_commands.c:310 Timer Test: 2 sleep 20 20042
2010-01-29 12:01:15.544336 [CONSOLE] mod_commands.c:310 Timer Test: 3 sleep 20 19928

tone_detect

Start Tone Detection on a channel.

Usage: tone_detect [ ]

unsched_api

Unschedule an api command.

Usage: unsched_api

url_decode

Usage: url_decode

Url decode a string.

url_encode

Url encode a string.

Usage: url_encode

user_data

Retrieves user information (parameters or variables) as defined in the directory.

Usage: user_data @ [attr|var|param]

Where user is the user’s id, domain is the user’s domain, var|param specifies whether the info we’re requesting is a variable/parameter, and the name is the name (key) of the variable.

Example:

user_data 1000@192.168.1.101 param password

will return a result of 1234, and

user_data 1000@192.168.1.101 var accountcode

will return a result of 1000 from the example user shown in [[Mod_commands#user_exists|user_exists]], and

user_data 1000@192.168.1.101 attr id

will return the user’s actual alphanumeric ID (i.e. “john”) when number-alias=”1000″ was set as an attribute for that user.

user_exists

Checks to see if a user exists; Matches user tags found in the directory and returns either true/false:

Usage: user_exists

Where key references a key specified in a directory’s user tag, user represents the value of the key, and the domain is the domain the user is assigned to.

Example:

user_exists id 1000 192.168.1.101

will return true where there exists in the directory a user with a key called id whose value equals 1000: In the above example, we also could have tested for randomvar:

user_exists randomvar 45 192.168.1.101

And we would have received the same results, but:

user_exists accountcode 1000 192.168.1.101

or,

user_exists password 1000 192.168.1.101

Would have returned false.

See Also

  • [[Channel_Variables|Channel Variables]]

[[Category:Integration]] [[Category:Configuration]] [[Category:API]] [[Category:Modules]]

Freeswitch内核之事件类型说明

Freeswitch内核之事件类型

事件 说明
3 Channel events 信道事件。
3.1 Channel states 信道状态。
3.2 CHANNEL_CALLSTATE 信道呼叫状态事件。
3.3 CHANNEL_CREATE 创建事件。
3.4 CHANNEL_DESTROY 销毁事件。
3.5 CHANNEL_STATE 呼叫状态事件。当一个信道切换通话状态时发送。此事件并不包含任何附加信息。
3.6 CHANNEL_ANSWER 呼叫应答事件。
3.7 CHANNEL_HANGUP 挂机事件。
3.8 CHANNEL_HANGUP_COMPLETE 挂机完成事件。
3.9 CHANNEL_EXECUTE PBX正在执行呼叫事件。
3.10 CHANNEL_EXECUTE_COMPLETE 执行完成。
3.11 CHANNEL_BRIDGE 一个呼叫两个端点之间的桥接事件。
3.12 CHANNEL_UNBRIDGE 停用桥接事件。
3.13 CHANNEL_PROGRESS 进度事件,外呼时对方提醒。或者入呼时提醒。
3.14 CHANNEL_PROGRESS_MEDIA 媒体进度事件,外呼时对方提醒。或者入呼时提醒。
3.15 CHANNEL_OUTGOING 创建一个外呼事件。
3.16 CHANNEL_PARK 一个呼叫被挂起(停放)在PBX中。
3.17 CHANNEL_UNPARK 一个呼叫被取消挂起(停放)在PBX中。
3.18 CHANNEL_APPLICATION 信道产生的应用程序就是事件application=event一般用来捕获呼转
3.19 CHANNEL_HOLD 信道保持,使用uuid_hold或者接收SDP的readonly
3.20 CHANNEL_UNHOLD 触发后uuid_hold关闭<uuid>或者接收到INVITE SDP= SendRecv的
3.21 CHANNEL_ORIGINATE 信道发起事件,触发完成发起(或桥)。
3.22 CHANNEL_UUID uuid事件表示唯一的ID通道已经改变。原来的ID将被报告的旧唯一ID。此事件会发生,当您使用参数origination_uuid时发出命令发起/桥。

4 System events
4.1 SHUTDOWN 设置以启动的FreeSWITCH的关机顺序。
4.2 MODULE_LOAD 模块加载
4.3 MODULE_UNLOAD 模块卸载
4.4 RELOADXML 重新加载已经配置的XML
4.5 NOTIFY 通知
4.6 SEND_MESSAGE 发送信息
4.7 RECV_MESSAGE 接收信息
4.8 REQUEST_PARAMS 请求参数
4.9 CHANNEL_DATA 信道数据
4.10 GENERAL 总体
4.11 COMMAND 命令
4.12 SESSION_HEARTBEAT session心跳
4.13 CLIENT_DISCONNECTED 客户端断开
4.14 SERVER_DISCONNECTED 服务器断开
4.15 SEND_INFO 发送信息
4.16 RECV_INFO 接收信息
4.17 CALL_SECURE 保密呼叫
4.18 NAT nat
4.19 RECORD_START 开始记录
4.20 RECORD_STOP 停止记录
4.21 PLAYBACK_START 开始播放
4.22 PLAYBACK_STOP 停止播放
4.23 CALL_UPDATE 更新呼叫

centos 的 yum 服务介绍

什么是 yum

Yum(全称 Yellow Dog Updater)是一个在 Fedora 和 RedHat 以及 CentOS 中的 Shell 前端软件包管理器。基于 RPM 包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包.

软件包来源

可供Yum下载的软件包包括 Fedora, Centos 和 RedHat 本身的软件包,其中 Fedora 的软件包是由Linux社区维护的,并且基本是自由软件。所有的包都有一个独立的PGP签名。

常用命令行命令

安装软件(以foo-x.x.x.rpm为例):

yum install foo-x.x.x.rpm

删除软件:

yum remove foo-x.x.x.rpm

或者

yum erase foo-x.x.x.rpm

升级软件:

yum upgrade foo

或者

yum update foo

查询信息:

yum info foo

搜索软件(以包含foo字段为例):

yum search foo

显示软件包依赖关系:

yum deplist foo

检查可更新的包:

yum check-update

清除全部:

yum clean all

清除临时包文件(/var/cache/yum 下文件):

yum clean packages

清除rpm头文件:

yum clean headers

清除旧的rpm头文件:

yum clean oldheaders

可安装和可更新的rpm包:

yum list 

已安装的包:

yum list installed

已安装且不在资源库的包:

yum list extras

可选项:

-e 静默执行  
-t 忽略错误
-R [分钟] 设置等待命令执行结束的最大时间
-y 自动应答,在执行 yum 操作时不需要用户交互确认
--skip-broken 忽略依赖问题
--nogpgcheck 忽略 GPG 校验过程
本文来自 阿里云

RegExp正则学习

正则匹配规则:

\d : 匹配一个数字
\w : 可以匹配一个字母或数字
. : 可以匹配任意字符
* : 表示任意个字符(包括0个)
+ : 表示至少一个字符
? : 表示0个或1个字符
{n} : 表示n个字符
{n,m} : 表示n-m个字符
[] : 表示范围
A|B : 可以匹配A或B
^ : 表示行的开头
$ : 表示行的结束

更多请移步 【廖雪峰博客】

使用win10的Hyper-V安装centOS 7

  1. 打开系统的Hyper-V
    进入控制面板,添加/删除程序中,找到打开/关闭windows功能,勾选.freamwork 3.5 及Hyper-V,确定后,系统会自动安装。
  2. 在系统菜单中找到Hyper-V,并打开

  3. 创建虚拟机,根据提示,进行(傻瓜式)添加虚拟机,注意一点,在本人尝试中,选择第一代和第二代的时候,我首先选择了第二代,以为第二代要比第一代TBU(高大上)一些,但是谁知,第二代在加载系统.iso文件的时候,根本没办法读取,进步了安装过程,只能……重来,选择了第一代。

  4. 到centOS官网上下载相应的系统,本人选择的是centOS minimal 7.X版本的,因为这个要比完整版小很多,相当于windows中的纯净版。

  5. 下载完成后,在添加的虚拟机中添加光盘驱动器,然后选择对应的系统.iso文件,点击开机,即可进入到安装系统界面,然后就是下一步->又一个傻瓜式的过程,不过要注意几点,就是在选择安装地方的时候,要记得去点击一下,然后选择你添加的虚拟磁盘,这样才能进入安装,否则无法进行安装。在安装过程中,要注意看某些选项中有红点点,然后就对应点击进去设置一下……

  6. 当系统安装成功后,就可以进入到系统了。然后就开始进行网络的配置。
    网络的配置需要先在虚拟机配置界面添加一个虚拟交换机,在虚拟机管理界面中,找到虚拟交换机管理器,点击,然后对应添加一个,连接类型选择外部网络,然后选择你物理机的网卡,然后确定即可。然后到添加的虚拟机中,进行对应的网络设置,设置 -> 网络适配器 -> 选择你添加的虚拟网络适配器,这时候,你的物理机可能无法进行连接外网了,然后到网络配置中,对应修改两个网卡的ip配置即可。
    然后就是centOS系统的网络配置,设置一个固定IP地址,然后,你可以选择性关闭防火墙,要不然,会出现很多问题……不想去纠结防火墙怎么设置就直接关闭!

  7. 至此,就可以通过物理机,使用ssh方式连接虚拟机centOS了。


下面是一些应用的设置

  1. centos minimal vim配色
    首先进行vim的安装
    [code lang=”bash”]
    yum -y install vim-enhanced
    [/code]
    安装完成后,可以在
    [code lang=”bash”]
    /usr/share/vim/vim72/colors
    [/code]
    下查看当前的配色方案有哪些。
    切换到 ~ 目录下,添加 .vimrc 文件,里面对应添加
    [code lang=”bash”]
    colorscheme darkblue
    [/code]
    其中,darkblue为配色方案,可以根据自己喜好和colors下的文件名选择。

打开 /etc/bashrc 文件,并在其中添加
[code lang=”bash”]
alias vi=’vim'(给vim起个别名叫vi…)
[/code]
然后运行
[code lang=”bash”]
source/etc/bashrc
[/code]

即可完成使用vi test.js 或者 vim test.js 都可以,并且有语法高亮显示的vim了。

论注释的重要性

好的注释,不仅能够让你的代码可读性更高,而且还能让你减少很多的工作量,比如能够根据注释,快速生成API文档。以下就是使用JSDoc快速生成API的方法。

首先安装JSDoc,安装命令如下:
npm install jsdoc –g

安装完成后,使用jsdoc –v 如果出现以下内容,说明安装成功

接下来,进入到项目目录下面,如果你的源代码放在根目录的src/目录下,那再根目录下新建conf.json文件,做为JSDoc的配置文件,并向里面添加以下内容:
[code lang=”js”]
{
“tags”: {
“allowUnknownTags”: true,
“dictionaries”: [“jsdoc”,”closure”]
},
“source”: {
“includePattern”: “.+\\.js(doc)?$”,
“excludePattern”: “(^|\\/|\\\\)_”
},
“plugins”: [],
“templates”: {
“cleverLinks”: false,
“monospaceLinks”: false
}
}
[/code]

用命令行打开根目录,使用以下命令即可生成API文档:
jsdoc src –r –c conf.json –d api

如果生成的API文档没有你代码里面相应的注释内容,说明注释内容不符合规范,具体规范可查阅JSDoc的API文档,http://www.css88.com/doc/jsdoc/
以下为vue的基本注释规范:

执行 jsdoc src –r –c conf.json –d api 即可生成对应的API文档,效果如下:

到此,你该知道良好的注释,是有多么的有用了吧?

git 常用命令

日常使用

[code lang=”bash”]

#查看当前仓库状态
$ git status

#添加所有修改的文件 || 添加指定文件或目录 到本地仓库队列中
$ git add . || git add filePath

#提交add完成的文件到本地仓库
$ git commit -m “这里是提交注释”

#再次查看当前啥情况
$ git status

#拉取远程仓库到本地仓库进行合并操作,
#此处如果远程仓库的有其他人修改并提交过相同的文件,则会出现冲突,
#git会自动进行合并操作,如果不能自动合并,则要进行手动合并,
#对相关文件进行合并后,再次返回第一条命令,如此反复
$ git pull || git pull origin master

#提交本地仓库到远程仓库
$ git push || git push origin master

[/code]

进阶使用

[code lang=”bash”]
git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态
git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。
git reset –hard HASH #返回到某个节点,不保留修改。
git reset –soft HASH #返回到某个节点。保留修改
git clean -df #返回到某个节点
git clean 参数
    -n 显示 将要 删除的 文件 和 目录
    -f 删除 文件
    -df 删除 文件 和 目录
[/code]
也可以使用:
git checkout . && git clean -xdf
来进行全部恢复

git分支创建与切换

[code lang=text]
$ git checkout -b dev
Switched to a new branch ‘dev’
[/code]

创建并切换到dev分支
相当于

[code lang=text]
$ git branch dev
$ git checkout dev
Switched to branch ‘dev’
[/code]

查看当前所在分支

[code lang=text]
$ git branch
* dev
master
[/code]

‘*’表示的就是当前所在分支

查看远程分支
$ git branch -a

【当合并代码出现冲突,出现rebase的时候…】
查看丢失的commit记录
git reflog

通过丢失的commit新建一个branch分支
git checkout -b dev 5aw24s2

切换到主分支
git branch master

合并分支
git merge dev

删除dev分支
git branch -d dev

查看文件修改记录
$ git log 文件路径
查看某次提交所修改的内容
$ git show hashID
或者
$ git show hashID 文件路径

xlsx.js学习

最近遇到个问题,为了让用户能够快速的上传数据,需要在开发的系统当中使用上传excel文件,一开始很是头疼,各种查资料都是搞不懂是个什么玩意,到底怎么实现也不清楚,经过认真研究后,终于找到了解决的办法,那就是使用了前端xlsx.js这个库。
开始做的时候,根据自己的理解,要进行excel数据的导入操作,那必须先进行文件的上传,然后在进行文件的读取,并把excel文件里面的数据解析出来。可看了xlsx.js的示例,发现它并没有进行上传的操作,而是直接就把文件解析出来了,且可以解析成原生excel格式、json格式还有其他类型格式,我主要用json格式来进行传输,所以主要研究了json格式。
具体实现如下:
1、前端页面中引用xlsx.js文件,xlsx.js文件下载
2、html中添加input标签,这里有两种方式,如果要用直接的选择文件空间,可以直接使用
的形式来进行操作,如果要用其它的按钮或者空间,可以把file空间设置为隐藏,,然后在通过js调用,触发此file控件的click事件即可。
3、监听file空间的change事件,并进行文件读取及解析
这里还用到的是HTML5中的FileReader()方法,此方法具体内容可自行进行百度。
实现的具体代码如下:

var X = XLSX;
var xl = document.getElementById('xlf');
if(xl.addEventListener){
    console.log(222);
    xl.addEventListener('change', function(e){
        var files = e.target.files;
        var f = files[0];
        var reader = new FileReader();
        var result = {};
        reader.onload = function(e) {
            var data = e.target.result;
            var wb = X.read(data, {type: 'binary'});
            wb.SheetNames.forEach(function(sheetName) {
                var roa = X.utils.sheet_to_row_object_array(wb.Sheets[sheetName]);
                if(roa.length > 0){
                    result[sheetName] = roa;
                }
            });
            var res = JSON.stringify(result, 2, 2);
            console.log(11);
            importExcle(result);
        };
        reader.readAsBinaryString(f);
    });
}

importExcle方法可对数据进行处理,如上传到服务器,或者输出到指定地方。

MySQL 5.7.14安装教程

Mysql 5.7.14安装教程

相比之前的mysql版本,5.7版本的mysql,可以说是改变得面目全非,不熟悉的人,安装起来就是完全不知头脑,我也是各种寻求网上教程,才得以解脱。下面就把我的受虐过程分享,让更多得人免受此版本数据库的困扰。

  1. 首先,它是要依赖.net framework的,而且是4.0版本。下面是一个能用的版本链接:
    http://libs.webshao.com/soft/tool/Microsoft.NET.exe

  2. 然后点击msi的安装包,可以看到下面这样的效果:
    MySQL安装1
    此处为保险起见,直接选择full安装,要不然后面步骤就不是一样了。只是说,完全安装的话,就会安装了一些乱七八糟的东西,但此处先不叙说其它安装。

  3. 然后下一步出现这样的界面
    MySQL安装2

  4. 此处要是你直接Next的话,将会出现这样的画面
    MySQL安装3
    所以只能进行execute,先把该装的装上吧!

    后面是一系列的下一步安装,最终会进入到mysql的配置文件配置。那里可以直接添加用户名和密码,也可以后期再进行添加,只是后期的话,没有图形界面,要进入命令模式了。

  5. 安装好后,要进行一些参数的设置,要不然用起来很不舒服。
    首先进行用户名、密码及一系列的设置。如果在配置过程输入过,那可忽略。新版本的MySQL的用户密码不再是password字段,改为了authentication_string字段,当然,设置密码的方法还是一样:
    (1)Cmd进入MySQL:cmd -> mysql –uroot –p
    此处如果无法使用mysql命令,自行环境变量配置。
    MySQL安装4

    如果首次使用,没有设置过用户名密码,则直接回车,设置过,则输入密码进入。
    (2)修改密码和允许外部访问:
    update user set host=”%”,authentication_string=password(‘root’) where user=’root’;
    然后刷新权限:
    FLUSH PRIVILEGES;

    即可用新密码登录,而且其他电脑也能访问了。

    (3)设置最大存储
    寻找到my.ini配置文件,如果在安装目录找不到,那就到C:\ProgramData 目录下面找,记事本打开,在最后添加一下内容:
    [mysqld]
    port=3306
    explicit_defaults_for_timestamp = TRUE
    max_allowed_packet = 64M
    tmp_table_size = 64M
    max_heap_table_size = 64M

    重启服务,单字段存储的内容就可达到64M了,否则数据一大了以后,就会导致崩溃无法添加的现象。

  6. 有的是解压好的安装文件,那就把MySQL添加到系统服务里面
    进入MySQL目录下的bin目录下,
    可先进行初始化
    bin\mysqld –defaults-file=d:\mysql57\my.ini –initialize
    再进行安装服务:
    运行mysqld –install MySQL defaults-file=d:\mysql57\my.ini
    即可安装服务
    MySQL安装5

    最后,提供个MySQL的安装包
    http://libs.webshao.com/soft/tool/mysql-installer-community-5.7.14.0.msi