每秒更新来自 api 的消息
Posted
技术标签:
【中文标题】每秒更新来自 api 的消息【英文标题】:Update messages from api every second 【发布时间】:2019-04-11 01:50:23 【问题描述】:我在我的 react 原生移动应用程序中使用react-native gifted-chat
作为我的聊天界面,在我的组件中,我将从一个 api 获取用户的消息并将其呈现在有天赋的聊天界面中,在有天赋的聊天中发送的任何消息也被发送到一个api,它将消息保存在db中。现在我想每秒更新一次消息状态,以便当其他用户也向它更新的当前用户发送消息时,我尝试使用设置间隔但模拟器总是挂起,请问更新消息的最有效方法是什么除了我所做的以外的数组
constructor(props)
super(props);
this.state =
messages: []
;
this.checker = this.checker.bind(this);
;
checker()
const params = this.props.navigation.state;
this.setState(loading: true);
var bodyParameters =
id: params.id,
receiver_id: params.receiver_id
/* var config =
headers: 'Authorization': "Bearer " + this.state.token
;*/
axios.post(
'http://10.0.2.2:8000/api/messages',
bodyParameters,
// config
).then((response) =>
this.setState(loading: false);
console.log(response);
var len = response.data.success?response.data.success.length:null;
for (let i = 0; i < len; i++)
let row = response.data.success[i];
console.log(row.id, row.user1.id);console.log("chat")
this.setState(prevState => (
messages: [...prevState.messages, _id: row.id, text: row.message,
createdAt: row.created_at, user: _id: row.user1.id,name: row.user1.first_name+' '+row.user1.last_name],
), console.log(this.state.messages));
console.log("checker");
;
).catch((error) =>
this.setState(loading: false);
console.log(error);
);
componentDidMount()
this.interval = setInterval(() => this.checker(), 1000);
componentWillUnmount()
clearInterval(this.interval);
componentWillMount()
const params = this.props.navigation.state;
/* var pusher = new Pusher('1363556f717d953dcf86',
cluster: 'mt1',
forceTLS: true
);
var channel = pusher.subscribe('private-messages.'+ params.id);
channel.bind('MessageSent', function(data)
console.log(data);
);*/
this.setState(loading: true);
var bodyParameters =
id: params.id,
receiver_id: params.receiver_id
/* var config =
headers: 'Authorization': "Bearer " + this.state.token
;*/
axios.post(
'http://10.0.2.2:8000/api/messages',
bodyParameters,
// config
).then((response) =>
this.setState(loading: false);
console.log(response);
var len = response.data.success?response.data.success.length:null;
for (let i = 0; i < len; i++)
let row = response.data.success[i];
console.log(row.id, row.user1.id);console.log("chat")
this.setState(prevState => (
messages: [...prevState.messages, _id: row.id, text: row.message,
createdAt: row.created_at, user: _id: row.user1.id,name: row.user1.first_name+' '+row.user1.last_name],
), console.log(this.state.messages));
console.log("contjii");
;
).catch((error) =>
this.setState(loading: false);
Alert.alert(
'Error',
'Internal Server Error, please try again later',
[
text: 'OK',
], );
console.log(error);
);
/* this.setState(
messages: [
_id: 1,
text: 'Hello developer',
createdAt: new Date(),
user:
_id: 1,
name: 'React Native',
avatar: 'https://placeimg.com/140/140/any',
,
// image: 'https://facebook.github.io/react/img/logo_og.png',
// additional custom parameters
sent : true,
received : true,
,
],
)*/
onSend(messages = [])
console.log(messages);
const params = this.props.navigation.state;
messages[0].sent = true;
var bodyParameters =
id: params.id,
receiver_id: params.receiver_id,
message: messages[0].text
/* var config =
headers: 'Authorization': "Bearer " + this.state.token
;*/
axios.post(
'http://10.0.2.2:8000/api/sendMessage',
bodyParameters,
// config
).then((response) =>
this.setState(loading: false);
console.log(response);
).catch((error) =>
this.setState(loading: false);
Alert.alert(
'Error',
'Internal Server Error, please try again later',
[
text: 'OK',
], );
console.log(error);
);
this.setState(previousState => (
messages: GiftedChat.append(previousState.messages, messages),
));
render()
const params = this.props.navigation.state;
return (
<GiftedChat
messages=this.state.messages
// inverted=false
onSend=messages => this.onSend(messages)
user=
_id: params.id,
/>
);
【问题讨论】:
【参考方案1】:代码的问题在于 setInterval 不断发送 API 调用,而不关心之前的调用是否返回。 这在服务器上一次排队了很多请求。要解决此问题,您应该等待 API 响应,然后再进行下一次 API 调用。
【讨论】:
【参考方案2】:处理此问题的最有效方法是使用 Web Sockets 协议,该协议会将通知从服务器发送到 UI 客户端。很难给你举个例子,因为我们不知道你的服务器堆栈,但是像 SignalR in.Net world 这样的东西在这里会很完美。
这里的前提是,服务器不会每秒向服务器询问新消息,而是会在有新消息时通知客户端。这样你会节省很多资源。
【讨论】:
我使用 Laravel 作为我的后端,我一次使用 pusher 作为我的 web socket,但是它限制了一天可以发送的消息,到目前为止我还没有找到一个 web socket是免费的,这就是为什么我想以老式的方式每秒更新消息 在我看来,Pusher 是一个服务而不是一个库。所以你发送一些数据给 Pusher,然后 Pusher 发送给你的客户端。我所说的是这样的:socketo.me 你可以配置你自己的 Laravel 服务器来使用这个库并向你的 UI 发送消息。不会有任何您需要支付的第三方参与。这是 Laravel 的广播文档:laravel.com/docs/5.7/broadcasting 你不需要使用 Pusher 来完成这项工作。 谢谢你,我会通读文档,然后我可能不得不切换到网络套接字以上是关于每秒更新来自 api 的消息的主要内容,如果未能解决你的问题,请参考以下文章
网站上的实时更新 - 每秒 1 个 ajax 是不好的做法?
如何区分“消息”更新和“回调查询”更新? (电报机器人 API)