我怎么能得到响应从服务器没有创建直线对象每次在微软Bot框架直线JS客户端(REACTJS)



我在使用userInput作为依赖数组的useEffect中传递getResponse()函数。每次用户发送输入时,都会触发此函数,并且每次都会创建新的直接对象。我面临的问题是,我正在创建机器人每次我发送请求到机器人。如何在初始渲染时只创建一次对象,然后使用该对象与bot连接?

请帮忙!

这是我遵循的botframework文档

这是我写的代码在ReactJS与机器人交流。

import React, { useEffect, useState } from "react";
import "./App.css"
import { DirectLine } from "botframework-directlinejs";
import { browserName, browserVersion, osName } from "react-device-detect";
import { ConnectionStatus } from 'botframework-directlinejs';
import Header from "./Components/Header";
import MainBody from "./Components/MainBody";
import BottomWrapper from "./Components/BottomWrapper";
function App() {
useEffect(() => {
const userIpDetails = fetchIp();
setUserIp(userIpDetails);
}, []);
// to fetch user IP
const fetchIp = async () => {
const response = await fetch("https://api.ipify.org/?format=json");
const ip = await response.json();
const userIP = ip.ip;
return userIP;
};
const [loaded, setLoaded] = useState(false);
const [message, setMessage] = useState("");
const [userInput, setUserInput] = useState([]);
const [messages, setMessages] = useState([]);
const [userIp, setUserIp] = useState("");
var client;
useEffect(() => {
setLoaded(true);
getResponse();
}, [userInput]);
// to get DirectLine Streaming Token
const getDirectLineStreamingToken = async function () {
const res = await fetch(
https://directline.botframework.com/v3/directline/tokens/generate,
{
method: "POST",
headers: {
Authorization:
`Bearer TOKEN`,
},
}
);
const { token } = await res.json();
return token;
};
// send request via message box
const sendRequest = () => {
console.log("request sent");
client
?.postActivity({
from: {
id: "my_id",
name: "Software Company",
avatarUrl:
"https://demos.telerik.com/kendo-ui/content/chat/VacationBot.png",
},
type: "message",
text: message,
channelData: {
iP: userIp,
platform: `${osName}`,
Browser: `${browserName} ${browserVersion}`,
},
})
?.subscribe(
(id) => console.log("Posted activity, assigned ID ", id),
(error) => console.log("Error posting activity", error)
);
};
// receive response from server
const getResponse = function () {
getDirectLineStreamingToken().then(function (token) {
client = new DirectLine({
domain: "https://directline.botframework.com/v3/directline",
token: token,
});
client.activity$.subscribe((activity) => {
onResponse(activity);
});
client.connectionStatus$
.subscribe(connectionStatus => {
switch(connectionStatus) {
case ConnectionStatus.Uninitialized:    // the status when the DirectLine object is first created/constructed
case ConnectionStatus.Connecting:       // currently trying to connect to the conversation
case ConnectionStatus.Online:           // successfully connected to the converstaion. Connection is healthy so far as we know.
case ConnectionStatus.ExpiredToken:     // last operation errored out with an expired token. Your app should supply a new one.
case ConnectionStatus.FailedToConnect:  // the initial attempt to connect to the conversation failed. No recovery possible.
case ConnectionStatus.Ended:            // the bot ended the conversation
}
console.log("connection status ", connectionStatus)
});
})
.catch((e) => console.log("bot error", e));;
};
// handle response received from server
const onResponse = function (activity) {
console.log("activity is ", activity);
let receivedResponse = activity.text;
if (activity.inputHint === "acceptingInput") {
setMessages([
...messages,
{ messageKey: receivedResponse, isbotmessage: true },
]);
}
};
const handleChange = function (event) {
setMessage(event.target.value);
console.log(event.target.value);
};
const handleKeyPress = function (event) {
if (event.key === "Enter") {
sendRequest();
setMessages([...messages, { messageKey: message, isbotmessage: false }]);
setUserInput([
...messages,
{ messageKey: userInput, isbotmessage: false },
]);
}
};
const handleClick = function (event) {
sendRequest();
setMessages([...messages, { messageKey: message, isbotmessage: false }]);
setUserInput([...messages, { messageKey: userInput, isbotmessage: false }]);
};
return loaded ? (
<div className="App">
<div className="chat-window">
<Header />
<MainBody messages={messages}/>
<BottomWrapper message={message} handleChange={handleChange} handleKeyPress={handleKeyPress} handleClick={handleClick}/>
</div>
</div>
) : (
<p>Loading...</p>
);
}
export default App;

您应该将DirectLineclient对象的创建以及订阅activityconnectionStatus移出函数配置useEffect()钩子仅运行一次。应该创建一次client对象,然后根据需要引用它。看看这篇关于如何实现这些选项的文章。

另外,因为您已经订阅了activityconnectionStatus,所以应该允许它们独立运行,以便它们能够按预期运行。当connectionStatus发生变化时,switch语句将检测到这一点。当满足不同的情况时,您可以通过useState()分配状态,并通过useEffect()钩子检测状态的变化。

最新更新