freeswitch 部署测试流程
目录
- 1)源码目录说明
- 1、conf
- 2、libs
- 3、srcipts
- 4、src(重要)
- 2)部署目录
- 1、conf(重要)
- autoload_configs
- 1、switch.conf.xml(优先级最高)
- 2、logfile.conf.xml(日志输出配置)
- 3、modules.conf.xml(定义加载的模块)
- dialplan
- sip_profiles
- 2、var目录(日志)
- 3、share 目录
- 1、自定义脚本存储位置
- 2、自定义声音文件
- 4、etc目录
- freeswitch.xml(初始化配置)
- vars.xml(全局配置)
- **日志级别:**
- 声音文件:
- 二、基础性安装
- 0)默认性设置
- 1、默认部署目录
- 2、默认最低版本
- 3、声音文件相关依赖包地址
- 语言包
- 音乐包
- 4、默认MRCP协议
- 5、语音编码
- 带宽计算占用
- 1)依赖包安装
- 2)部署目录
- 1、布置安装包
- 2、部署安装
- 3、声音文件安装
- 自定义安装语音:
- 自动安装语音文件:
- 4、安装MRCP协议模块
- 5、配置安装的语音文件
- 1、配置加载语言
- vars.xml加载
- freeswitch.xml加载
- 2、配置媒体编码支持
- 兼容性编码
- 协商编码策略
- 6、ACL访问控制配置
- 客户端访问配置
- 7、DTMF模式选择
- ①使用2833模式外呼
- ②使用inbound模式外呼
- ③sipInfo模式外呼
- sdp携带数字检测
- 8、使用第三方mrcp模块(可选)
- 阿里模块
- 1、ali-unimrcp.xml
- 2、网关配置
- 3)启动相关检测
- ①启动/停止freeswitch
- ②查看端口是否启动
- ③登录/退出freeswitch
- ④网关状态
- ⑤验证电话
- 4)抓包检测
- 5)开启SIP日志跟踪
全文基于1.6.x版本进行调试,后续版本或许有变更,不会涉及相关性
1)源码目录说明
1、conf
可以参阅官网来配置业务所需功能,不一定完全自己开发(我这边暂时全部自己处理)
2、libs
第三方目录,具体列表可以参考同一目录下的
modules.conf
例如:我们所需的:
unimrcp
,sofia-sip(主要通信用到)
3、srcipts
包含安装时用到的各种脚本支持,可以参照
/src/mod/lanuages
来辅助判断
4、src(重要)
代码核心目录
可以适当性的改变源码调整适合自己的模式,修改内置模块内容
mod
目录名称 | 概要说明 | 主要内容 |
---|---|---|
asr_tts | 典型语音合成与识别 | 可以替换需要的asr与tts |
dialplans | 拨号规则(对来电路由解析) | asterisk(内联)、xml方式(常用) |
endpoints | 端点模块 | mod_sofia(默认SIP协议栈) |
formats | 兼容的内容格式 | |
xml_int | 一些初始化时的xml | 可以客制化对应模块 |
applications | mod_db(涉及数据库) | |
directories | LDAP实现 | |
event_handlers | 事件处理模块 | 包含队列和内容等处理 |
languages | 支持不同开发语言的模块 | |
say | 支持不同自然语言的模块 | |
timers | 时间及定时器模块 |
2)部署目录
1、conf(重要)
配置目录,关键目录
autoload_configs
模块配置
1、switch.conf.xml(优先级最高)
默认采用
vars.xml
配置,更改后有时需要刷新。若是本配置,配置即可生效
# 例如配置日志,等同于vars.xml内配置的级别效果
<param name="loglevel" value="debug"/>
2、logfile.conf.xml(日志输出配置)
例如日志输出位置,默认为相对路径
var/log/freeswitch.log
<!--<param name="logfile" value="/var/log/freeswitch.log"/>-->
3、modules.conf.xml(定义加载的模块)
这里显示的模块是会被加载的,源码中的
modules.conf
则是表示会编译。(但是可能会存在编译不成功等,这时是不会被加载的)
#1、可以预先开放MRCP协议模块
开放 asr_tts/mod_unimrcp 注释#2、开放语音支持
# 根据自己需要的语音
# say/mod_say_zh :简体中文
# say/mod_say_en : 英文(默认开启)
开放 say/mod_say_en
# 补救安装 make mod_say_en-install
一同编译后:
# (1)freeswitch.xml
`<section name="languages" description="Language Management">`
出现`<X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>`
也可以后续手动增加
#(2)vars.xml
出现 `<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/en/us/callie"/>`
#(3)freeswitch/etc/freeswitch/lang出现对应en模块
dialplan
拨号规则文件
sip_profiles
sip配置文件
2、var目录(日志)
默认采用SQLite数据库,当然也可以自定义数据库(但是目前没有使用)
var/log/freeswitch
这对我们日常捕获之日很重要
3、share 目录
1、自定义脚本存储位置
share/freeswitch/scripts
2、自定义声音文件
share/freeswitch/sounds
4、etc目录
freeswitch.xml(初始化配置)
路径:
etc/freeswitch/vars.xml
引入配置的初始化配置
vars.xml(全局配置)
全局变量配置
日志级别:
# 例如设置日志级别debug
<!-- various debug and defaults -->
<X-PRE-PROCESS cmd="set" data="call_debug=false"/>
# debug模式
<X-PRE-PROCESS cmd="set" data="console_loglevel=debug"/>
# info 模式
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/>
声音文件:
二、基础性安装
①需要用root权限安装,涉及一些高权限的问题
②需要
yum
命令及外网访问权限
0)默认性设置
1、默认部署目录
/opt/freeswitch/setup
2、默认最低版本
freeswitch-1.6.20.tar.gz
公网地址:http://files.freeswitch.org/freeswitch-releases/?C=M;O=D
3、声音文件相关依赖包地址
公网地址(无需翻墙即可):http://files.freeswitch.org/releases/sounds/
常用语音包如下:(常用us、zh、hk、music)
Tips: 这里主要以截止时间为2021.9.16的最新版本记录
语言包
国家 | 地区方言 | 精度 | 呼叫人名 | 版本 |
---|---|---|---|---|
en | us | 8000 | callie/allison | 1.0.52/1.0.1 |
en | us | 16000 | callie/allison | 1.0.52/1.0.1 |
en | us | 32000 | callie/allison | 1.0.52/1.0.1 |
en | us | 48000 | callie/allison | 1.0.52/1.0.1 |
zh | hk | 8000 | sinmei | 1.0.51 |
zh | hk | 16000 | sinmei | 1.0.51 |
zh | hk | 32000 | sinmei | 1.0.51 |
zh | hk | 48000 | sinmei | 1.0.51 |
zh | cn | 8000 | sinmei | 1.0.51 |
zh | cn | 16000 | sinmei | 1.0.51 |
zh | cn | 32000 | sinmei | 1.0.51 |
zh | cn | 48000 | sinmei | 1.0.51 |
音乐包
精度 | 版本 |
---|---|
8000 | 1.0.52 |
16000 | 1.0.52 |
32000 | 1.0.52 |
48000 | 1.0.52 |
4、默认MRCP协议
媒体资源控制协议(Media Resource Control Protocol)
默认采取V2版本的MRCP协议也就是SIP控制协议
Tips:目前存在两种版本,版本2使用SIP作为控制协议,版本1使用RTSP控制协议
5、语音编码
带宽计算占用
带宽=包长度×每秒包数=包长度×(1/打包周期)=(Ethernet头+IP头+UDP头+RTP头+有效载荷)×(1/打包周期)=(208bit +160bit+64bit+96bit +有效载荷)×(1/打包周期)=(528bit+(打包周期(秒)×每秒的比特数))×(1/打包周期)=( 528 / 打包周期 ) + 每秒比特数
常规编码表
G723: 24byte(6.3k/s)、20byte(5.3k/s)
name of encoding sample/frame | samplie/frame | default rate | ms/frame | ms/packet | sampling |
---|---|---|---|---|---|
DVI4 | sample | 4 | 20 | var. | |
G711(a/u) | sample | 64 | 20 | 16000 | |
G722 | sample | 8 | 20 | 16000 | |
G723 | frame | N/A | 30 | 30 | 8000 |
G728 | frame | N/A | 2.5 | 20 | 8000 |
G729(a/b) | frame | N/A | 10 | 20 | 8000 |
PCMU | sample | 8 | 20 | var. | |
PCMA | sample | 8 | 20 | var. |
# 结合编码表计算
G711:20ms打包,带宽为 ( 528/20 + 64) Kbit/s=90.4 Kbit/sG729:20ms打包,带宽为 ( 528/20 + 8 ) Kbit/s= 34.4 Kbit/sG723:5.3k,30ms打包,带宽为 ( 528/30 + 5.3 ) Kbit/s=22.9 Kbit/s
1)依赖包安装
yum install -y git gcc-c++ wget alsa-lib-devel autoconf automake bison bzip2 curl-devel e2fsprogs-devel flite-devel gdbm-devel gnutls-devel ldns-devel libcurl-devel libedit-devel libidn-devel libjpeg-devel libmemcached-devel libogg-devel libsndfile-devel libtiff-devel libtheora-devel libtool libvorbis-devel libxml2-devel lua-devel lzo-devel ncurses-devel net-snmp-devel openssl-devel opus-devel pcre-devel perl perl-ExtUtils-Embed pkgconfig postgresql-devel python-devel soundtouch-devel speex-devel sqlite-devel unbound-devel unixODBC-devel libuuid-devel which zlib-devel net-tools libvpx libvpx-devel yasm
2)部署目录
mkdir -p /opt/freeswitch/setup
tip: p参数是递归创建目录,即使上级目录不存在,会按目录层级自动创建目录
1、布置安装包
一般建议1.6大版本内,次版本号以双数为稳定版
放置到部署目录内 /opt/freeswitch/setup
2、部署安装
进入目录解压
tar -xvf ./freeswitch-1.6.20.tar.gz
配置安装地址并且编译安装
Tips: 如果想偷懒可以先直接参照第4步才进行安装
cd /opt/freeswitch/setup/freeswitch-1.6.20
# 配置安装前缀
./configure --prefix=/opt/freeswitch/freeswitch-1.6.20
# 编译安装
make & make install
3、声音文件安装
freeswitch 需要语音包以支持音頻播放,若缺失这部分会导致拨号时直接挂断的问题
进入声音文件目录:
/opt/freeswitch/setup/freeswitch-1.6.20/share/freeswitch/sounds
自定义安装语音:
建议为每个语言单独建立一个父目录以适合配置
根据需要,依次下载所有精度的语音包
例如:hk语言:
#48000 精度
wget http://files.freeswitch.org/releases/sounds/freeswitch-sounds-zh-hk-sinmei-48000-1.0.51.tar.gz
#32000 精度
wget http://files.freeswitch.org/releases/sounds/freeswitch-sounds-zh-hk-sinmei-32000-1.0.51.tar.gz
#16000 精度
wget http://files.freeswitch.org/releases/sounds/freeswitch-sounds-zh-hk-sinmei-16000-1.0.51.tar.gz
#8000 精度
wget http://files.freeswitch.org/releases/sounds/freeswitch-sounds-zh-hk-sinmei-8000-1.0.51.tar.gz# 四个精度在同一个文件夹下解压,会自适应合并
tar -xvf freeswitch-sounds-zh-hk-sinmei-48000-1.0.51.tar.gz
tar -xvf freeswitch-sounds-zh-hk-sinmei-32000-1.0.51.tar.gz
tar -xvf freeswitch-sounds-zh-hk-sinmei-16000-1.0.51.tar.gz
tar -xvf freeswitch-sounds-zh-hk-sinmei-8000-1.0.51.tar.gz
自动安装语音文件:
#进入源代码目录中执行
cd /opt/freeswitch/setup/freeswitch-1.6.20
#下列录音文件中可选择其一#安装低精度录音文件
make sounds-install
make moh-install#安装高清录音文件
make cd-sounds-install
make cd-moh-install
4、安装MRCP协议模块
这边采用V2版本也就是基于SIP控制协议
#进入源代码目录
cd /opt/freeswitch/setup/freeswitch-1.6.20#编辑模块配置 modules.conf
# 开放 asr_tts/mod_unimrcp 注释make mod_unimrcp-install
5、配置安装的语音文件
1、配置加载语言
/opt/freeswitch/etc/freeswitch
可采取方式有两种:①
freeswitch.xml
②vars.xml
Tips:最终vars.xm也是会被freeswitch加载的
vars.xml加载
# 英文加载
# en/us/callie 为sound目录下直接解压的主目录
<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/en/us/callie"/># 中文加载
# zh/cn/link 为sound目录下直接解压的主目录
<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/zh/cn/link"/>
freeswitch.xml加载
#开启中文、英文
<section name="languages" description="Language Management"><X-PRE-PROCESS cmd="include" data="lang/zh/*.xml"/> <X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
</section>#这里配置需要对应
开放的内容参考 `modules.conf.xml` 模块开放语言,编译
例如:
say/mod_say_zh #模块注释
#安装模块,即可安装模块
make mod_say_zh-install
2、配置媒体编码支持
实际上需要两端编码共同支持才能正常呼叫成功并解码编码
兼容性编码
#注释默认值
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,G722,PCMU,PCMA,VP8"/>
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,G722,PCMU,PCMA,VP8"/>
#切换为,主要是使用G711算法支持媒体提升兼容性
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,G711,PCMU,PCMA,VP8"/>
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,G711,PCMU,PCMA,VP8"/>
协商编码策略
编码协商问题:https://blog.csdn.net/yetyongjin/article/details/88848897
#混频处理,FS自动转换
<X-PRE-PROCESS cmd="set" data="media_mix_inbound_outbound_codecs=true"/>
6、ACL访问控制配置
/opt/freeswitch/etc/freeswitch/autoload_configs/acl.conf.xml
可以自定义访问控制
#例如创建一个列表 `my_acl`
# 允许:127.0.0.1/32
# 禁止:172.16.2.103/20
# 下列用到的FreeSwitch的ip
<list name="my_acl" default="deny"><node type="allow" domain="$${domain}"/> <node type="allow" cidr="127.0.0.1/32" /><node type="deny" cidr="172.16.2.103/20"/><node type="deny" cidr="172.16.2.106/20"/>
</list>
客户端访问配置
以socket的形式,对外提供控制FS一种途径,使得可以用
fs_cli
访问FS外呼使用
inbound
模式,默认不修改是RFC2833
编辑
/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml
<configuration name="event_socket.conf" description="Socket Client"><settings><param name="nat-map" value="false"/><!-- 配置任意网络可访问 --><param name="listen-ip" value="0.0.0.0"/> <param name="listen-port" value="8021"/><!-- 自定义密码 --><param name="password" value="ClueCon"/><!-- 使用定义的ACL配置:acl --><param name="apply-inbound-acl" value="my_acl"/></settings>
</configuration>
7、DTMF模式选择
①使用2833模式外呼
默认就是2833模式,通常要支持101携带数字
#freeswitch/etc/freeswitch/sip_profile/internal.xml、extranal.xml
<param name="rfc2833-pt" value="101"/>
②使用inbound模式外呼
#DTMF(双音多频)定义:由高频音和低频音的两个正弦波合成表示数字按键(0~9 * # A B C D)。(1)SIPINFO (带外检测方式)
(2)RFC2833 (带内检测方式)
(3)INBAND (带内检测方式)在选择压缩比很高码率很低的codec,比如G.723.1和G.729A等,建议不要使用INBAND模式,因为INBAND DTMF数据在进行复杂编解码后会产生失真,造成DTMF检测发生偏差或失败
freeswitch/etc/freeswitch/sip_profile/internal.xml 、extranal.xml
#默认为RFC2833
<param name="dtmf-type" value="inband"/>
# 关闭101,若开启这个配置,会自动转为2833
<param name="rfc2833-pt" value="101"/>
③sipInfo模式外呼
freeswitch/etc/freeswitch/sip_profile/internal.xml、extranal.xml
#默认为RFC2833
<param name="dtmf-type" value="info"/>
# 关闭101,若开启这个配置,会自动转为2833
<param name="rfc2833-pt" value="101"/>
sdp携带数字检测
寻找参数: send * bytes to udp
接着寻找:INVITE
m=audio 16724 RTP/AVP 0 8 3 101 # 这里包含了数字 0、8、3、101a=rtpmap:0 PCMU/8000a=rtpmap:8 PCMA/8000a=rtpmap:3 GSM/8000a=rtpmap:101 telephone-event/8000 # 101a=fmtp:101 0-16 #101a=ptime:20
8、使用第三方mrcp模块(可选)
主要针对
/opt/freeswitch/etc/freeswitch/autoload_configs/unimrcp.conf.xml
修改
阿里模块
/opt/freeswitch/etc/freeswitch/autoload_configs/unimrcp.conf.xml
修改
<configuration name="unimrcp.conf" description="UniMRCP Client"><settings><!-- 配置tts与asr模块配置 --><param name="default-tts-profile" value="ali-unimrcp"/><param name="default-asr-profile" value="ali-unimrcp"/></settings><!-- 配置阿里mrcp配置 start --><!-- 放置在autoload_configs同级目录 --><profiles><X-PRE-PROCESS cmd="include" data="../mrcp_profiles/*.xml"/></profiles><!-- 配置阿里mrcp配置 end-->
</configuration>
1、ali-unimrcp.xml
/opt/freeswitch/etc/freeswitch/mrcp_profiles
下新建ali-unimrcp.xml
阿里语音IP: 172.16.7.80
freeswitchIP: 172.16.2.103 #具体设置可以在第六步完成【ACL访问控制配置】
<include><profile name="ali-unimrcp" version="2"><param name="server-ip" value="阿里语音的IP"/><!-- server-port:阿里语音端口 --><param name="server-port" value="7010"/><param name="client-ip" value="freeswitchIP"/><!-- client-port:客户端服务器端口 --><param name="client-port" value="9988"/> <param name="sip-transport" value="tcp"/><!-- ua-name:代理服务器名称 --><param name="ua-name" value="Freeswitch"/><!-- sdp-origin:呼叫终端源头 --><param name="sdp-origin" value="Freeswitch"/><!-- rtp-ip:代理服务器IP --><param name="rtp-ip" value="freeswitchIP"/><param name="rtp-port-min" value="4240"/><param name="rtp-port-max" value="4259"/><param name="codecs" value="L16/96/8000"/></profile>
</include>
2、网关配置
配置:
/opt/freeswitch/etc/freeswitch/sip_profiles/external
例如自定义网关配置名称:
ringo.xml
from-domain: 192.167.34.212 #允许进入的地址,若不设置则不限制
proxy: 192.168.21.13:5082 # 电话网关地址和端口
<gateway name="ringo"><param name="username" value="none"/><param name="password" value="none"/><param name="caller-id-in-from" value="true"/><!-- proxy:电话网关地址和端口 --><param name="proxy" value="192.168.21.13:5082"/><param name="register" value="false"/><!-- from-domain:可以不设置,等于可以允许任意domain访问 --><param name="from-domain" value="180.167.34.212"/>
</gateway>
3)启动相关检测
①启动/停止freeswitch
# 启动
/opt/freeswitch/bin/freeswitch -nc
# 停止
/opt/freeswitch/bin/freeswitch -stop
②查看端口是否启动
netstat -nlpt
③登录/退出freeswitch
登录freeswitch,具体若访问不了,参考【7、inbound模式配置】
#登入freeswitch
/opt/freeswitch/bin/fs_cli -H127.0.0.1 -pClueCon -P8021
#退出freeswitch
输入/bye退出freeswitch登录
④网关状态
sofia status
#查看external:ringo
对应地址为设置地址
⑤验证电话
#vos开启透传后,输入显示号码:0755811111
# 约定显示透传号码:0755811111
# 测试手机号码:15111111117
originate {origination_caller_id_number=0755811111}sofia/gateway/ringo/15111111117 &echo
4)抓包检测
#网卡名称:ens192
tcpdump -i ens192 -W ./freeswitch.cap
5)开启SIP日志跟踪
在fs_cli 控制界面上输入命令:
开启sip消息显示: sofia global siptrace on关闭sip消息显示: sofia global siptrace off
freeswitch 部署测试流程相关推荐
- 作为专业的测试人员,如何全流程操作部署测试环境
文章目录 一.前提概要 二.隐藏的技能树 三.实战出真知 四.总结一句话 一.前提概要 题主从事了10+年的测试岗位,来谈谈在公司如何整明白部署应用服务(环境)?因为在面试的时候,都会遇到提问:会部署 ...
- freeswitch部署及网关调试
freeswitch部署及网关调试 目录 freeswitch部署及网关调试... - 1 - 一.freeswitch部署... - 3 - (一)基础部署... - 3 - (二)根据实际情况需求 ...
- BERT模型从训练到部署全流程
BERT模型从训练到部署全流程 Tag: BERT 训练 部署 缘起 在群里看到许多朋友在使用BERT模型,网上多数文章只提到了模型的训练方法,后面的生产部署及调用并没有说明. 这段时间使用BERT模 ...
- 怎么测试服务器端口是否对外开放_从零开始内建你的安全测试流程
一. 安全测试的意义 安全问题,没发生的时候我们可以侥幸,一旦发生生产安全问题,对很多公司来说可能就是黑天鹅事件了.平台的安全,是我们测试中不可舍弃的一环,而且需要长期持续的关注. 二. 从哪里入手 ...
- 从零开始内建你的安全测试流程
一. 安全测试的意义 安全问题,没发生的时候我们可以侥幸,一旦发生生产安全问题,对很多公司来说可能就是黑天鹅事件了.平台的安全,是我们测试中不可舍弃的一环,而且需要长期持续的关注. 二. 从哪里入手 ...
- 一个项目的整个测试流程
最近一直在进行接口自动化的测试工作,同时对于一个项目的整个测试流程进行了梳理,希望能对你有用~~~ 需求分析: 整体流程图: 需求提取 -> 需求分析 -> 需求评审 -> 更新后的 ...
- 从测试流程角度,阿里P8大佬对产品质量的一些总结思考...
两个熟悉的场景: 生产环境出现问题,解决问题,原因复盘.责任分配到人: 无休止的测试-回归-再测试-再回归测试,已经投入了很大精力,但仍对项目质量不信心: 如果自己所负责或参与的项目经常遇到上面的两种 ...
- 技术分享 | 一文带你了解测试流程体系
软件测试是软件质量保证的关键步骤.越早发现软件中存在的问题,修复问题的成本就越低,软件质量也就越高,软件发布后的维护费用越低. 为了能更好的保障软件质量,在软件测试的实践中,慢慢形成了一些流程用来达到 ...
- 测试流程如何有效落地?
前言:之前有小伙伴问了我一个问题:作为测试leader,你该如何有效落地测试流程? 这个问题看起来很简单,只要落地流程做个宣讲然后有人执行就行了,但仔细一想却没那么简单.团队人员有多少?技术和经验如何 ...
最新文章
- python编写自定义模块_python 自定义Server酱模块编写
- C#使用ExecuteReader返回DataReader既有查询结果集又有输出参数或返回值的使用注意事项...
- 深入理解TCP/IP协议族
- java数组可扩展_[转载]Java数组扩容算法及Java对它的应用
- 安装虚拟机和docker封装
- Flex 当鼠标悬停在DataGrid某行上时用datatoolField显示当前行
- python3异步协程爬虫,simpyder
- 【STM32入门】STM32基础理论知识
- 链家北京二手房交易数据分析
- linux复制dos命令,Linux mcopy复制MSDOS格式档案命令详解
- 差分放大电路及动态分析
- 生物信息学|Extracting Drug-Drug Interactions with Attention CNNs
- CPU通用寄存器 eax ebx ecx edx esp ebp esi edi
- 初次配置zookeeper——Invalid config, exiting abnormally
- chrome/edge解决不能打开问题
- shell sftp 命令大全
- C语言|从入门到尽量别放弃
- Oracle的常见错误及解决办法
- Python 的Tkinter包系列之七:好例子补充
- Java开发记事本(完整版)
热门文章
- python - sklearn 计算精准率(Precision)
- 牛奶可乐经济学之Q15:减税真的能帮到富人吗?
- Effective STL中文版:50条有效使用STL的经验(双色)
- 微信小程序新闻详情页面效果实现
- 解决 小程序界面数据不显示问题
- sklearn 的基本机器学习(分类方法)
- oracle定时器每天下午6点_每天下午5到7点吃它,补肾效果杠杠的!
- 华为ensp交换机vlan划分三种接入模式详解-----网络通信原理
- Scrapy爬虫报错HTTP status code is not handled or not allowed
- 往事如烟 - 笑傲江湖