测试场景
向 rasa server 发送一条消息,除非一连串的耗时操作,每个操作执行前都返回一条消息。
即,客户端发送一条聊天消息,rasa 机器人间隔返回多条消息回复。
同时作为统一消息格式的测试工具。
客户端模拟
本来打算用 python socket.io client 实现,但是考虑到目前大部分使用场景都是基于浏览器。 所以还是基于 html js 来实现一个客户端更合适。
也顺便把 socket.io 版本的 chatui.io 聊天界面实现。
测试逻辑
- 建立 socket.io 连接
 - 建立连接后,发送消息,触发指定的 rasa custom action
 - rasa custom action 中,返回消息 utter_a, sleep 3 秒后,返回消息 utter_b
 
custom action
错误的做法:
class ActionHelloWorld(Action):
    def name(self) -> Text:
        return "action_hello_world"
    async def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        dispatcher.utter_message(text="Hello World!")
        time.sleep(3)  # sleep 3 seconds
        dispatcher.utter_message(text="Hello World!")
        return []
这个写法,还是会等待第二条消息一并返回。没有达到两条异步返回的效果。
参考:
https://forum.rasa.com/t/delay-in-dispatcher-utter-message/52687/10
似乎是不能在一个 action 中异步返回多个消息,只能拆分成多个 action 来实现这个效果。
实际测试,确实如此,不可以直接在一个 custom action 的 python 代码中通过多个 dispatcher.utter_message 来实现异步返回多条消息。
只能通过拆分为多个不同的 action 来实现。从代码复用,及解耦的角度来看,这样也是合理的。
class ActionHelloWorld(Action):
    def name(self) -> Text:
        return "action_hello_world"
    async def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        dispatcher.utter_message(text="Hello World!")
        return [
            FollowupAction("action_hello_world2"),
        ]
class ActionHelloWorld2(Action):
    def name(self) -> Text:
        return "action_hello_world2"
    async def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        time.sleep(3)  # sleep 3 seconds
        dispatcher.utter_message(text="Hello World Again!")
        return []
效果如图
果然跟预期的一致。
同时,我测试了现有基于 HTTP 的 REST 接口,也确实是等待两条一并返回的。
web 前端 js 代码
user_uttered, 及 bot_uttered 为 rasa socket.io 默认的事件名。
var socket = io.connect("http://localhost:5005", {path: '/my_socket.io'})
socket.on("connect", function () {
  console.log("socketio connected");
  socket.emit("user_uttered", { message: "/hello_world" });
});
socket.on("bot_uttered", function (data) {
  console.log("bot uttered: " + data);
  showMessage(data);
});
function showMessage(data) {
  const messages = document.getElementById("messages");
  const liElement = document.createElement("li");
  liElement.textContent = `text: ${data.text}`;
  messages.appendChild(liElement);
}
查看合集
关于作者 🌱
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式