lab04-Node-RED 函数节点

一、目录

1. 实验目的

掌握函数节点的使用

2. 知识要点

  • 函数节点在 node-red 中表示一个 JavaScript 函数块,用来处理节点接收到的消息。
  • 这些消息作为一个名为 msg 的 JavaScript 对象传入。
  • 通常有一个 msg.payload 属性,包含消息正文。
  • 函数被期望返回一个 message 对象(或多个消息对象),但是可以选择不返回任何东西以阻止流。
  • 发送消息:函数既可以使用“return”向流中的下一个节点传递消息,也可以调用 node.send(messages)。它可以返回或是发送
        一个单一的消息对象——传递给连接到第一个输出的节点
        一组消息对象——传递给连接到相应输出的节点
      如果数组的任何元素本身都是一组消息,那么多条消息就会被发送到相应的输出。如果返回 null,无论是单独还是作为数组的元素,都不会传递任何消息。要记录任何信息或报告错误,可以使用以下功能:
node.log("Log message")
node.warn("Warning")
node.error("Error")

3. 实验步骤

3.1 使用函数节点创建并返回多个信息

1. step1: 按照下图组建流
1.实现
1.1 拖拽出四个节点。
2. step2: 修改其中的函数节点,使其具有两个输出口
2.实现
2.1 设置两个输出口
2.2 然后把节点连接起来
3. step3: 将以下代码添加到函数节点
3.实现
3.1代码添加到函数节点
代码
var msg1 = {payload:"first out of output 1"};
var msg2 = {payload:"second out of output 1" };
var msg3 = {payload:"third out of output 1"} ;
var msg4 = { payload: "only message from output 2"} ;
return[[msg1, msg2, msg3],msg4] ;
4. step4: 部署,你在调试窗口看到了什么?
4.实现
4.1部署
4.2运行
image.png
5.实验总结 第一个调试节点一口气收到了 3 条消息,而第二个调试节点收到了一条消息,消息的内容跟刚刚输入的代码有关系,跟输入的消息没有任何关系,因为输入的是时间戳。对比分析:
return msg ; //一 个 返 回 值
return [ [ msg1 , msg2 , msg3 ] , msg4 ] ; //一 组 返 回 值

3.2 通过判断语句进行数据分类

         Switch 控件可以进行数据的分流,它属于功能控件。函数控件是功能控件里,功能最强的,它可以实现switch 控件的功能。
1. step1: 按下图组装组件

注意这里 inject 节点输入的是数字而不是时间戳,分别为 100,10,1

实现
1.拖拽节点
2.设置参数

剩余2个,重复以上操作即可

2. step2: 修改函数节点使其有 3 个输出口
实现
1.设置参数,设置3 个输出口
2.将所有的节点连接起来,如下图
3. step3: 修改函数节点相关代码,使其能够进行分类判断
if(msg.payload > 10)
{
    return [msg, null, null];
} else if(msg.payload === 10)
{
    return [null, msg, null];
} else
{
    return [null, null, msg];
}
实现
1.设置代码

4. step4: 部署并调试,查看调试窗口

实现

5. step5: 试一试,按照字符串分类也是可以的


如果要求当检测到第一个字符串”apple”,让数据输出在第一个输出口 OUT1,当检测到第二个字符串”banana”,让数据输出在第一个输出口 OUT2,当检测到第三个字符串”orange”,让数据输出在第一个输出口 OUT3。您该如何修改程序?

实现
1.拖拽节点
2.设置节点

其余2个节点重复以上操作。

  • 设置另一个节点配置,以及代码


  • 设置代码如下图
if (msg.payload == "apple") {
    return [msg, null, null];
} else if (msg.payload == "banana") {
    return [null, msg, null];
} else if (msg.payload == "orange") {
    return [null, null, msg];
}

再把所有节点连接起来,并部署,如下图


3.3 单个数据计算

1. step1: 新建对象返回 拖入 inject 节点,并把输入的内容改为数字;拖入 debug 节点用来观察现象,拖入函数节点并做如下修改:
  • 名称设置为乘以 2
  • 函数部分添加如下代码:
var newMsg = {payload: msg.payload*2};
return newMsg;

其中,var newMsg = {payload: msg.payload * 2 } 语句的意思是,新建一个对象,名为 newMsg,它有 payload 属性,并且 payload 的值为 msg.payload 的两倍。最后返回的是 newMsg,也就是新建的这个对象。部署并运行,可以看到现象是,调试窗口显示的数值是输入的两倍。说明函数节点的功能实现了。消息是通过 msg 对象传过来的,可不可以不新建一个对象,直接修改 msg.payload 呢?

实现
1.拖入 inject 节点、并把输入的内容改为数字
2.拖入 debug 节点用来观察现象
3.拖入函数节点并做如下修改
4.部署并观察数据变化
2. step2: 修改原有对象模式 将 step1 中的函数修改一下:
msg.payload = msg.payload*2;
return msg;

部署,可以发现结果一样正确。

实现
1.部署与对比

3.4 使用数组进行数据截取与组装

通常,在实际通信的时候不会只传递一个数组,信息的传递依赖于数组,数组中不同位置的数字也会有不同的含义,例如,第一个数字表示 ID,第二个数字表示数组长度,第三个数字表示温度等等,一般会有一个通信协议来规定。所以,如何取出有用的数据,或者按要求把数据进行组装很重要。现在,假如收到了一串数据,数据共 16 位,我们只用到后 8 位,前边的 8 位都不要了,如何来操作?

1. step1: 编辑 inject 节点 编辑 inject 节点使其输入一组数组
实现
1.拖入节点,并连接
2.设置节点参数
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
2. step2: function 节点接入 inject 节点实现数据截断
image.png
var temp = new Buffer([0, 0, 0, 0, 0, 0, 0, 0]);
for( var i = 0; i < 8; i++)
temp[i] = msg.payload[i + 8];
msg.payload = temp;
return msg;
实现
1.设置函数节点参数
3. step3: 部署运行,查看截断的效果
实现
1.效果

3.5 模拟温度数值计算

由于通信方式的限制,数据在发送时,常常要转换为 8 位的字符来发送。在数字电路里,只有高电平和低电平两种情况,所以数据在发送时,就只能使用 1 和 0 个数字。这个 1 或 0,称之为 1 位。通常,8 位可以传输一个字符。2 的 8 次方是 256,所以小于 256 的数字,可以用 8 位来传输。而大于或等于 256 的数字,就要分成 2 个 8 位传输了。另外,8 位的数据可以用两个十六进制的数来表示,比如 0101 1010 可以表示为 0x5a,所以通常会用十六进制来表示通信协议中的数。
  例如,我们现在想传输十进制的数字 14859,大于 256,所以要分包传送。十进制转化为二进制是0011 1010 0000 1011,在通过硬件发送数据时,如果不考虑校验或者起始位以及高位还是地位在前,就只考虑数字的发送,那么总线上的电平可能是低低高高,高低高低,低低低低,高低高高。把这个数字写成十六进制,是 0x3a 与 0x0b,或 0x3a0b,0x 用来表示这是个十六进制的数字。0x3049 可以通过这种方式换算成 10 进制:数字拆成单个字符来分析,a 到 f 的数对应 10 到 15,在第几位上,就乘以几个 16。0x3a0b =3×16×16×16 + 10×16×16 + 11=14859。或者直接使用 16 进制进行计算,0x3a0b=0x3a×256+0x0b
  当然,通信协议是可以进行特殊的规定,例如表示 4 位的温度,34.56°C,要通过十六进制的数字进行分包发送,就是 0Xd80/100。我们现在规定,十六进制的温度高位 ×256+ 低位 = 温度 ×100。接下来尝试解析温度的数据。
  我们使用 inject 节点输入数组 [0xd,0x80],由于 inject 节点里不支持直接输入十六进制的数字,所以输入 [13,128]。这两个数组的值是一样的。

1. step1: 使用 inject 节点模拟温度数据输入
实现
1.拖入节点,并连接
2.设置 inject 节点,参数
2. step2: 接入 function 节点并计算显示的温度数据值
image.png
实现
1.设置function 节点,参数代码
var temp = (msg.payload[0] * 256 + msg.payload[1]) / 100;
msg.payload = temp;
return msg;
3. step3: 部署,运行,查看输出
实现效果

全部代码

[
    {
        "id": "2285f598968b299e",
        "type": "tab",
        "label": "流程 3",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "fa937b8668055899",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 40,
        "wires": [
            [
                "7bddb6dd44a1f495"
            ]
        ]
    },
    {
        "id": "7bddb6dd44a1f495",
        "type": "function",
        "z": "2285f598968b299e",
        "name": "function 2",
        "func": "var msg1 = {payload:\"first out of output 1\"};\nvar msg2 = {payload:\"second out of output 1\" };\nvar msg3 = {payload:\"third out of output 1\"} ;\nvar msg4 = { payload: \"only message from output 2\"} ;\nreturn[[msg1, msg2, msg3],msg4] ;\n\n",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 40,
        "wires": [
            [
                "65d5e74df22c54e2"
            ],
            [
                "b593fe3dbbd92174"
            ]
        ]
    },
    {
        "id": "65d5e74df22c54e2",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 9",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 20,
        "wires": []
    },
    {
        "id": "b593fe3dbbd92174",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 10",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 60,
        "wires": []
    },
    {
        "id": "621d5293fa63f6e1",
        "type": "function",
        "z": "2285f598968b299e",
        "name": "function 3",
        "func": "if(msg.payload > 10)\n{\n    return [msg, null, null];\n} else if(msg.payload === 10)\n{\n    return [null, msg, null];\n} else\n{\n    return [null, null, msg];\n}\n",
        "outputs": 3,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 260,
        "y": 260,
        "wires": [
            [
                "4639173c87098450"
            ],
            [
                "ef253b64ec25fa55"
            ],
            [
                "fb9da972c119ccdb"
            ]
        ]
    },
    {
        "id": "4639173c87098450",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 11",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 460,
        "y": 180,
        "wires": []
    },
    {
        "id": "ef253b64ec25fa55",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 12",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 460,
        "y": 260,
        "wires": []
    },
    {
        "id": "fb9da972c119ccdb",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 13",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 460,
        "y": 320,
        "wires": []
    },
    {
        "id": "e833aa26a5885270",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "100",
        "payloadType": "num",
        "x": 110,
        "y": 200,
        "wires": [
            [
                "621d5293fa63f6e1"
            ]
        ]
    },
    {
        "id": "8380dd33dda6db06",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "10",
        "payloadType": "num",
        "x": 110,
        "y": 260,
        "wires": [
            [
                "621d5293fa63f6e1"
            ]
        ]
    },
    {
        "id": "367ebcc185265f41",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 110,
        "y": 300,
        "wires": [
            [
                "621d5293fa63f6e1"
            ]
        ]
    },
    {
        "id": "827ba21a6ff429fc",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "apple",
        "payloadType": "str",
        "x": 110,
        "y": 440,
        "wires": [
            [
                "e55b0d9c5e4a1dbf"
            ]
        ]
    },
    {
        "id": "08ff10bdf4cef0df",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "banana",
        "payloadType": "str",
        "x": 110,
        "y": 480,
        "wires": [
            [
                "e55b0d9c5e4a1dbf"
            ]
        ]
    },
    {
        "id": "05a89fc7b88cbf50",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "orange",
        "payloadType": "str",
        "x": 110,
        "y": 540,
        "wires": [
            [
                "e55b0d9c5e4a1dbf"
            ]
        ]
    },
    {
        "id": "e55b0d9c5e4a1dbf",
        "type": "function",
        "z": "2285f598968b299e",
        "name": "function 4",
        "func": "if (msg.payload == \"apple\") {\n    return [msg, null, null];\n} else if (msg.payload == \"banana\") {\n    return [null, msg, null];\n} else if (msg.payload == \"orange\") {\n    return [null, null, msg];\n}\n",
        "outputs": 3,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 260,
        "y": 480,
        "wires": [
            [
                "761f58e1183ae2b9"
            ],
            [
                "5d93c6a18efeb657"
            ],
            [
                "565963cd11a03d53"
            ]
        ]
    },
    {
        "id": "761f58e1183ae2b9",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 14",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 440,
        "wires": []
    },
    {
        "id": "5d93c6a18efeb657",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 15",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 480,
        "wires": []
    },
    {
        "id": "565963cd11a03d53",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 16",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 540,
        "wires": []
    },
    {
        "id": "8b16f36974053654",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "10",
        "payloadType": "num",
        "x": 110,
        "y": 660,
        "wires": [
            [
                "a89933ec35aa53f2"
            ]
        ]
    },
    {
        "id": "e480658147d8c7b7",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 17",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 660,
        "wires": []
    },
    {
        "id": "a89933ec35aa53f2",
        "type": "function",
        "z": "2285f598968b299e",
        "name": "function 5",
        "func": "msg.payload = msg.payload*2;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 660,
        "wires": [
            [
                "e480658147d8c7b7"
            ]
        ]
    },
    {
        "id": "f8e4cd626c04bcd5",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]",
        "payloadType": "bin",
        "x": 110,
        "y": 760,
        "wires": [
            [
                "85107ae0ccdbccf1"
            ]
        ]
    },
    {
        "id": "85107ae0ccdbccf1",
        "type": "function",
        "z": "2285f598968b299e",
        "name": "function 6",
        "func": "var temp = new Buffer([0, 0, 0, 0, 0, 0, 0, 0]);\nfor( var i = 0; i < 8; i++)\ntemp[i] = msg.payload[i + 8];\nmsg.payload = temp;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 760,
        "wires": [
            [
                "dea8aaae03f6492d"
            ]
        ]
    },
    {
        "id": "dea8aaae03f6492d",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 18",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 480,
        "y": 780,
        "wires": []
    },
    {
        "id": "458cec50b66a1164",
        "type": "inject",
        "z": "2285f598968b299e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "[13,128]",
        "payloadType": "bin",
        "x": 110,
        "y": 920,
        "wires": [
            [
                "c7cfb7dc54312a34"
            ]
        ]
    },
    {
        "id": "c7cfb7dc54312a34",
        "type": "function",
        "z": "2285f598968b299e",
        "name": "function 7",
        "func": "var temp = (msg.payload[0] * 256 + msg.payload[1]) / 100;\nmsg.payload = temp;\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 920,
        "wires": [
            [
                "0a627ee0471128d2"
            ]
        ]
    },
    {
        "id": "0a627ee0471128d2",
        "type": "debug",
        "z": "2285f598968b299e",
        "name": "debug 19",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 480,
        "y": 920,
        "wires": []
    }
]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容