freeswitch的安装和配置

目录

1. 安装freeswitch
├── 1.1 相关地址
├── 1.2 安装基础包
├── 1.3 安装依赖包
├── 1.4 代码依赖包
├── 1.5 编译
├── 1.6 安装声音文件
├── 1.7 新版本安装 上面的安装依赖包不用git到工程文件夹
├── 1.8 设置链接符号,便于使用
├── 1.9 部署成服务
├── 1.10 配置文件
│ ├── 1.10.1 添加H263~H2641.7版本
│ └── 1.10.2 添加授权注册 需要编译mod_xml_curl
└── 1.11 相关命令

2. 错误解决
├── 2.1 freeswitch.service start request repeated too quickly, refusing to start
├── 2.2 fs_cli连接不上
├── 2.3 mod_xml_curl.c:459 Binding has no url!
├──2.4. 呼叫慢
└──2.5. 重启后出错

3. 拨号计划
├── 3.1 相关文档
├── 3.2 安装mod_curlmod_flite
│ ├──3.2.1 配置modules.conf
│ ├──3.2.2 安装libflite-devel
│ ├──3.2.3 重新编译
│ └──3.2.4 配置modules.conf.xml
├── 3.3 构建拨号计划00_fsm.xml
│ └──3.3.1 MSB配置
├── 3.4 拨号计划参数
├── 3.5 拨号记录CDR
│ └──3.5.1 采用mod_odbc_cdr模块
│ │ ├──3.5.1.1 配置modules.conf
│ │ ├──3.5.1.2 编译安装
│ │ ├──3.5.1.3 配置modules.conf.xml
│ │ ├──3.5.1.4 配置odbc_cdr.conf.xml
│ │ └──3.5.1.5 生成表
└── 3.4 拨号计划参数

4. 配置wss实现webrtc

5. freeswitch端口
├── 5.1 基本端口
└── 5.2 rtp端口范围


1. 安装freeswitch

1.1 相关地址

1.2 安装基础包

$ sudo yum install epel-release vim -y
$ curl -O  http://files.freeswitch.org/freeswitch-releases/freeswitch-1.6.6.tar.bz2
$ sudo yum install bzip2 -y
$ tar xvjf freeswitch-1.6.6.tar.bz2

1.3 安装依赖包

$ sudo yum install gcc-c++ sqlite-devel zlib-devel libcurl-devel pcre-devel  speex-devel ldns-devel  libedit-devel  openssl-devel -y
$ sudo yum install libjpeg-devel lua-devel libsndfile-devel libyuv-devel git libtool -y

1.4 代码依赖包

$ cd freeswitch-1.6.6
$ cd libs/
$ git clone https://freeswitch.org/stash/scm/sd/libyuv.git
$ cd libyuv/
$ make -f linux.mk CXXFLAGS="-fPIC -O2 -fomit-frame-pointer -Iinclude/"
$ sudo make install
$ sudo cp /usr/lib/pkgconfig/libyuv.pc /usr/lib64/pkgconfig/
$ cd ..
$ git clone https://freeswitch.org/stash/scm/sd/libvpx.git
$ cd libvpx/
$ sudo yum install yasm -y
$ ./configure --enable-pic --disable-static --enable-shared
$ make
$ sudo make install
$ sudo cp /usr/local/lib/pkgconfig/vpx.pc /usr/lib64/pkgconfig/
$ cd ..
$ git clone https://freeswitch.org/stash/scm/sd/opus.git
$ cd opus/
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ sudo cp /usr/local/lib/pkgconfig/opus.pc /usr/lib64/pkgconfig
$ cd ..
$ git clone https://freeswitch.org/stash/scm/sd/libpng.git
$ cd libpng/
$ ./configure
$ make
$ sudo make install
$ sudo cp /usr/local/lib/pkgconfig/libpng* /usr/lib64/pkgconfig/

1.5 编译

$ cd freeswitch-1.6.6
$ ./configure
$ make
$ sudo make install

1.6 安装声音文件

$ sudo make cd-sounds-install
$ sudo make cd-moh-install

1.7 新版本安装 上面的安装依赖包不用git到工程文件夹

$ git clone https://freeswitch.org/stash/scm/fs/freeswitch.git
$ cd freeswitch
$ sh support-d/prereq.sh
$ sh bootstrap.sh
$ ./configure --prefix=/usr/local/freeswitch
$ make
$ sudo make install

1.8 设置链接符号,便于使用

$ sudo ln -sf /usr/local/freeswitch/bin/freeswitch /usr/local/bin/
$ sudo ln -sf /usr/local/freeswitch/bin/fs_cli /usr/local/bin/

1.9 部署成服务

sudo vim /usr/lib/systemd/system/freeswitch.service

[Unit]
Description=freeswitch
After=syslog.target
After=network.target

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/home/mintcode
ExecStart=/usr/local/freeswitch/bin/freeswitch
ExecStop=/usr/local/freeswitch/bin/freeswitch -stop 
Restart=always

[Install]
WantedBy=multi-user.target

1.10 配置文件

  • conf\sip_profiles\internal.xml 配置sip信息
1.10.1 添加H263~H2641.7版本
  1. $ sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml<load module="mod_h26x"/>去掉注释
  2. $ sudo vim /usr/local/freeswitch/etc/freeswitch/vars.xml
  <X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,G722,PCMU,PCMA,VP8,VP9,H263,H263-1998,H263-2000,H264"/>
  <X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,G722,PCMU,PCMA,VP8,VP9,H263,H263-1998,H263-2000,H264"/>
1.10.2 添加授权注册 需要编译mod_xml_curl
  1. $ sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml<load module="mod_xml_curl"/>去掉注释
  2. $ sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/xml_curl.conf.xml
    <binding name="directory">
      <param name="gateway-url" value="http://192.168.1.173:20501/freeswitch/dicectory" bindings="directory"/>
    </binding>
  1. MSB配置
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="netty4-http:http://{{msb.hostName}}:20501/freeswitch/dicectory"
    />
    <setHeader headerName="dial-string">
      <constant>
        {presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}
      </constant>
    </setHeader>
    <setHeader headerName="user">
      <javaScript>
        decodeURIComponent(request.headers.get('user'))
      </javaScript>
    </setHeader>
    <transform>
      <simple>
        <![CDATA[ <document type="freeswitch/xml">
        <section name="${header.section}">
        <domain name="${header.domain}">
        <params>
        <param name="dial-string" value="${header.dial-string}"/></params>
        <groups>
          <group name="default">
            <users>
              <user id="${header.user}">
                <params><param name="password" value="1234"/></params>
              </user>
            </users>
          </group>
        </groups>
        </domain></section></document>
        ]]>
      </simple>
    </transform>
    <removeHeaders pattern="*" />
    <setHeader headerName="Content-Type">
      <simple>
        text/xml
      </simple>
    </setHeader>
  </route>
</routes>

1.11 相关命令

  1. 显示哪些用户已注册 sofia status profile internal reg
  2. 控制台显示info级别日志 fs_cli -l info

2. 错误解决

2.1 freeswitch.service start request repeated too quickly, refusing to start

#去掉下面的配置项
WorkingDirectory=/home/mintcode

2.2 fs_cli连接不上

sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml

<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <!-- Allow socket connections from any host -->
    <param name="listen-ip" value="127.0.0.1"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
  </settings>
</configuration>

2.3 2016-03-08 14:29:50.925294 [ERR] mod_xml_curl.c:459 Binding has no url!

sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/xml_curl.conf.xml

<configuration name="xml_curl.conf" description="cURL XML Gateway">
  <bindings>
    <binding name="example">
      <!-- Allow to bind on a particular IP for requests sent -->
      <!--<param name="bind-local" value="$${local_ip_v4}" />-->
      <!-- The url to a gateway cgi that can generate xml similar to
           what's in this file only on-the-fly (leave it commented if you dont
           need it) -->
      <!-- one or more |-delim of configuration|directory|dialplan -->
      <!-- <param name="gateway-url" value="http://www.freeswitch.org/gateway.xml" bindings="dialplan"/> -->
      <!-- set this to provide authentication credentials to the server -->
      <!--<param name="gateway-credentials" value="muser:mypass"/>-->
      <!--<param name="auth-scheme" value="basic"/>-->

      <!-- optional: this will enable the CA root certificate check by libcurl to
           verify that the certificate was issued by a major Certificate Authority.
           note: default value is disabled. only enable if you want this! -->
      <!--<param name="enable-cacert-check" value="true"/>-->
      <!-- optional: verify that the server is actually the one listed in the cert -->
      <!-- <param name="enable-ssl-verifyhost" value="true"/> -->

      <!-- optional: these options can be used to specify custom SSL certificates
           to use for HTTPS communications. Either use both options or neither.
           Specify your public key with 'ssl-cert-path' and the private key with
           'ssl-key-path'. If your private key has a password, specify it with
           'ssl-key-password'. -->
      <!-- <param name="ssl-cert-path" value="$${certs_dir}/public_key.pem"/> -->
      <!-- <param name="ssl-key-path" value="$${certs_dir}/private_key.pem"/> -->
      <!-- <param name="ssl-key-password" value="MyPrivateKeyPassword"/> -->
      <!-- optional timeout -->
      <!-- <param name="timeout" value="10"/> -->

      <!-- optional: use a custom CA certificate in PEM format to verify the peer
           with. This is useful if you are acting as your own certificate authority.
           note: only makes sense if used in combination with "enable-cacert-check." -->
      <!-- <param name="ssl-cacert-file" value="$${certs_dir}/cacert.pem"/> -->

      <!-- optional: specify the SSL version to force HTTPS to use. Valid options are
           "SSLv3" and "TLSv1". Otherwise libcurl will auto-negotiate the version. -->
      <!-- <param name="ssl-version" value="TLSv1"/> -->

      <!-- optional: enables cookies and stores them in the specified file. -->
      <!-- <param name="cookie-file" value="$${temp_dir}/cookie-mod_xml_curl.txt"/> -->

      <!-- one or more of these imply you want to pick the exact variables that are transmitted -->
      <!--<param name="enable-post-var" value="Unique-ID"/>-->

    </binding>

    <binding name="directory">
      <param name="gateway-url" value="http://192.168.1.173:20501/freeswitch/dicectory" bindings="directory"/>
    </binding>

  </bindings>
</configuration>

2.4. 呼叫慢

sudo vim /usr/local/freeswitch/etc/freeswitch/dialplan/default.xml

     <condition field="${default_password}" expression="^1234$" break="never">
        <action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
        <action application="log" data="CRIT Open $${conf_dir}/vars.xml and change the default_password."/>
        <action application="log" data="CRIT Once changed type 'reloadxml' at the console."/>
        <action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
        <action application="sleep" data="3000"/>
      </condition>

2.5 重启后 failure to connect to CORE_DB

答案地址:http://comments.gmane.org/gmane.comp.telephony.freeswitch.user/72474

rm /usr/local/freeswitch/var/lib/freeswitch/db/core.db

3. 拨号计划

3.1 相关文档

3.2 安装mod_curlmod_flite

3.2.1 配置modules.conf

sudo vim /home/mintcode/freeswitch/modules.conf

applications/mod_curl
asr_tts/mod_flite
3.2.2 安装libflite-devel
$ cd libs/
$ git clone https://freeswitch.org/stash/scm/sd/libflite.git
$ cd libflite/
$ ./configure  --enable-pic --disable-static --enable-shared && make
$ sudo make install
$ sudo cp /usr/local/lib/pkgconfig/flite.pc /usr/lib64/pkgconfig
3.2.3 重新编译
$ cd /home/mintcode/freeswitch
$ ./configure --prefix=/usr/local/freeswitch
$ make
$ sudo make install
3.2.4 配置modules.conf.xml

sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml

    <load module="mod_curl"/>
    <load module="mod_flite"/>

3.3 构建拨号计划00_fsm.xml

sudo vim /usr/local/freeswitch/etc/freeswitch/dialplan/public/00_fsm.xml

  1. continue默认把它设置为false,设为true表示FS在当前分机号的所有action都解析成功是否继续。
  2. break表示判断后的行为,有以下值:

On-true:第一次匹配后停止查找 <br />
On-false:默认值,第一次失败后停止查找 <br />
Always:不管匹配与否都停止 <br />
Never: 无论匹配与否都继续查找 <br />

<include>
  <extension name="public_fsm">
        <condition field="${channel_name}" expression="@([^@]*)$" break="never" >
           <action application="set" data="domain_name=$1"/>
        </condition>
        <condition field="destination_number" expression="^fsm" break="never">
             <action application="set" data="continue_on_fail=true"/>
             <action application="curl" data="http://192.168.1.173:20500/savefsinfo/test post caller_id_name=${caller_id_name}&destination_number=${destination_number}"/>
             <action application="log" data="${curl_response_data}" />
             <action application="sleep" data="3000"/>
             <action application="bridge" data="user/${destination_number}@${domain_name}"/>
             <!--
             <action application="answer"/>
             <action application="sleep" data="1000"/>
             -->
             <!-- speak words -->
             <!--
             <action application="set" data="tts_engine=flite"/>
             <action application="set" data="tts_voice=slt"/>
             <action application="speak" data="Jingle bells  Jingle bells  jingle all the way"/> 
             -->
             <!-- call api http://192.168.1.173:2015/ -->
             <!--
             <action application="curl" data="http://192.168.1.173:20500/savefsinfo/test post caller_id_name=${caller_id_name}&destination_number=${destination_number}&case=${last_bridge_hangup_cause}"/>
             <action application="log" data="${curl_response_data}" />
             -->
        </condition>
        <condition field="${default_password}" expression="^1234$" break="never">       
          <action application="sleep" data="1000"/> -->
          <action application="bridge" data="user/${destination_number}@${domain_name}"/>
        </condition>
  </extension>
</include>
3.3.1 MSB配置
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="netty4-http:http://{{msb.hostName}}:{{restful.port}}/savefsinfo/{routerId}?httpMethodRestrict=POST"
    />
    <convertBodyTo type="java.lang.String" />
    <setHeader headerName="CamelRedis.Key">
      <simple>
        fs:${header.routerId}
      </simple>
    </setHeader>
    <setHeader headerName="CamelRedis.Value">
      <javaScript>
        var result={ 'appName': 'launchr', 'appToken':'verify-code' }; request.body.split('&').forEach(function(a){var
        key=a.split('=');result[key[0]]=key[1]}); result.case=result.case||'USER_NOT_REGISTERED';
        result.userName=result.caller_id_name; result.to=[result.destination_number];
        request.body=JSON.stringify(result);
      </javaScript>
    </setHeader>
    <to uri="spring-redis://{{redis.hostName}}:{{redis.port}}?command=SET&serializer=#redisSerializer"
    />
    <removeHeaders pattern="*" />
    <setHeader headerName="Content-Type">
      <constant>
        application/json
      </constant>
    </setHeader>
    <setHeader headerName="CamelHttpMethod">
      <constant>
        POST
      </constant>
    </setHeader>
    <to uri="netty4-http:http://192.168.1.251:20001/launchr/chat/voip" />
  </route>
</routes>

3.4 拨号计划参数

变量名称 描述
caller_id_name 呼叫方的名称
destination_number 呼叫方所拨打的号码
direction 当前呼叫段是入站inbound或出站outbound
channel_name 此调用的入站通道的名称,例如:sofia/sales/John_Smith@192.168.1.1
state 状态,例如CS_EXECUTECS_HANGUP
bridge_hangup_cause 呼叫结束原因,例如NO_ANSWERNORMAL_CLEARINGUSER_BUSY
last_bridge_hangup_cause 最后呼叫结束的原因
动作 描述
answer 应答呼叫
bridge 桥叫到另一会话
log 日志文件中写入一条消息
hangup 断开呼叫
playback 播放音频文件或音流
set 通道设置变量
transfer 转移呼叫到另一个会话

3.5 拨号记录CDR

3.5.1 采用mod_odbc_cdr模块
3.5.1.1 配置modules.conf

sudo vim /home/mintcode/freeswitch/modules.conf

event_handlers/mod_cdr_sql
event_handlers/mod_json_cdr
3.5.1.2 编译安装
$ sudo yum install unixODBC mysql-connector-odbc -y
$ sudo make mod_odbc_cdr
$ sudo make mod_odbc_cdr-install
$ sudo cp /home/mintcode/freeswitch/src/mod/event_handlers/mod_odbc_cdr/conf/autoload_configs/odbc_cdr.conf.xml  /usr/local/freeswitch/etc/freeswitch/autoload_configs/.
$ sudo make mod_json_cdr
$ sudo make mod_json_cdr-install
$ sudo cp /home/mintcode/freeswitch/src/mod/event_handlers/mod_json_cdr/conf/autoload_configs/json_cdr.conf.xml  /usr/local/freeswitch/etc/freeswitch/autoload_configs/.
3.5.1.3 配置modules.conf.xml

sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml

    <load module="mod_odbc_cdr"/>
    <load module="mod_json_cdr"/>
3.5.1.4 配置odbc_cdr.conf.xml

sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/odbc_cdr.conf.xml

 <param name="odbc-dsn" value="odbc://DRIVER=mysql;SERVER=192.168.1.249;UID=root;PWD=p@ssw0rd;DATABASE=fs"/>

sudo vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/json_cdr.conf.xml

  <param name="url" value="http://192.168.2.92:20001/launchr/chat/voipcdr"/>
3.5.1.5 生成表
 CREATE TABLE cdr_table_a_leg (
   CallId varchar(50) DEFAULT NULL,
   orig_id varchar(50) DEFAULT NULL,
   term_id varchar(50) DEFAULT NULL,
   ClientId varchar(50) DEFAULT NULL,
   IP varchar(50) DEFAULT NULL,
   IPInternal varchar(50) DEFAULT NULL,
   CODEC varchar(50) DEFAULT NULL,
   directGateway varchar(50) DEFAULT NULL,
   redirectGateway varchar(50) DEFAULT NULL,
   CallerID varchar(50) DEFAULT NULL,
   TelNumber varchar(50) DEFAULT NULL,
   TelNumberFull varchar(50) DEFAULT NULL,
   sip_endpoint_disposition varchar(50) DEFAULT NULL,
   sip_current_application varchar(50) DEFAULT NULL
 ); 
 CREATE TABLE cdr_table_b_leg (
   CallId varchar(50) DEFAULT NULL,
   orig_id varchar(50) DEFAULT NULL,
   term_id varchar(50) DEFAULT NULL,
   ClientId varchar(50) DEFAULT NULL,
   IP varchar(50) DEFAULT NULL,
   IPInternal varchar(50) DEFAULT NULL,
   CODEC varchar(50) DEFAULT NULL,
   directGateway varchar(50) DEFAULT NULL,
   redirectGateway varchar(50) DEFAULT NULL,
   CallerID varchar(50) DEFAULT NULL,
   TelNumber varchar(50) DEFAULT NULL,
   TelNumberFull varchar(50) DEFAULT NULL,
   sip_endpoint_disposition varchar(50) DEFAULT NULL,
   sip_current_application varchar(50) DEFAULT NULL
 );
 CREATE TABLE cdr_table_both (
   CallId varchar(50) DEFAULT NULL,
   orig_id varchar(50) DEFAULT NULL,
   TEST_id varchar(50) DEFAULT NULL
 );

4. 配置wss实现webrtc

配置方案

5. freeswitch端口

5.1 基本端口

FireWall Ports  Network Protocol    Application Protocol    Description

1719    UDP H.323 Gatekeeper RAS port

1720    TCP H.323 Call Signaling

3478    UDP STUN service    Used for NAT traversal

3479    UDP STUN service    Used for NAT traversal

5002    TCP MLP protocol server

5003    UDP Neighborhood service

5060    UDP & TCP   SIP UAS Used for SIP signaling (Standard SIP Port, for default Internal Profile)

5070    UDP & TCP   SIP UAS Used for SIP signaling (For default "NAT" Profile)

5080    UDP & TCP   SIP UAS Used for SIP signaling (For default "External" Profile)

8021    TCP ESL Used for mod_event_socket *

16384-32768 UDP RTP/ RTCP multimedia streaming  Used for audio/video data in SIP and other protocols

5066    TCP Websocket   Used for WebRTC

7443    TCP Websocket   Used for WebRTC
5.2 rtp端口范围

conf/autoload_configs/switch.conf.xml

<param name="rtp-start-port" value="16384"/>
<param name="rtp-end-port" value="16389"/>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容