[英]How do I make material-ui progress bar update with large number of web socket messages causing render to happen often
[英]updateLastConsumedMessageIndex freezes causing no update in messages
當組件被安裝時,通道要么從現有的抓取,要么創建一個新的。 此通道稍后會保存在 state 中,以便在組件中保持持久性。 單擊組件時,所有通道消息都會更新為已使用。
該代碼屬於“今日輪班頻道”欄目。 右側代碼是單獨的。
Senario:當我單擊一個用戶時 onTaskSelect 被調用,這會在設置所有消耗的消息后觸發右側的整個用戶聊天。 這里出現問題 1 和 2 。 現在我單擊另一個用戶並單擊返回到以前單擊的用戶問題 3 發生
問題:
1) 它不更新消費的消息並且總是返回零。
2) 它停止接收來自joinOrCreate function中調用的 .on 偵聽器的新消息。
3)關於錯誤的重復點擊響應
SyncError:在mapTransportError( http://localhost:3000/static/js/0.chunk.js:162153:12 )在http://localhost:localhost: 12處禁止訪問身份(狀態:403,代碼:54007) /js/0.chunk.js:162210:20
注意:頻道設置一次,除非頁面刷新,否則永遠不會離開
注意:右側的整個聊天工作正常,並且位於單獨的模塊中。
注意:客戶端在應用程序開始時被初始化為上下文,該上下文在應用程序從打開到關閉的整個生命周期中持續存在。
const TaskCard = props => {
const [lastMessage, setLastMessage] = useState({})
const [open, setOpen] = useState(false)
const [unread, setUnread] = useState(0)
const [channel, setChannel] = useState({})
const joinOrCreate = useCallback(async() => {
try{
const fetchedChannel = await props.client.getChannelByUniqueName(props.task.id.toString())
let joined = fetchedChannel
if(fetchedChannel.state.status !== "joined") {
joined = await fetchedChannel.join()
}
console.log()
joined.getMessages()
.then(messages => {
if(messages.items.length > 0) {
if(joined.lastConsumedMessageIndex < messages.items.length - 1) {
setUnread(true)
}
const recent_message = messages.items[messages.items.length - 1]
const limit_message = recent_message.body.slice(0,14)
setLastMessage({
body: limit_message.length === 14? (limit_message + '...') : limit_message,
time: recent_message.timestamp,
index: recent_message.index,
})
}
})
joined.on('messageAdded', messageUpdated)
setChannel(joined)
}
catch(ch) {
console.log(ch)
try{
const newChannel = await props.client.createChannel({
uniqueName: props.task.id.toString(),
friendlyName: 'General Chat Channel'
})
let joined = newChannel
if(newChannel.state.status !== "joined") {
joined = await newChannel.join()
}
joined.getMessages()
.then(messages => {
if(messages.items.length > 0) {
const recent_message = messages.items[messages.items.length - 1]
setLastMessage({
body: recent_message.body,
time: recent_message.timestamp,
})
}
})
joined.on('messageAdded', messageUpdated)
setChannel(joined)
}
catch(e) {
console.log(e)
}
}
}, [props.client, props.task.id])
const messageUpdated = message => {
const limit_message = message.body.slice(0,14)
setLastMessage({
body: limit_message.length === 14? (limit_message + '...') : limit_message,
time: message.timestamp,
index: message.index
})
}
const onTaskSelect = () => {
// console.log(lastMessage.index)
console.log(channel.uniqueName)
if(lastMessage.body) {
channel.updateLastConsumedMessageIndex(+lastMessage.index)
.then(res => {
console.log(res)
})
.catch(e => {
// console.log(props.client)
// console.log(channel)
console.log(e)
})
}
props.onTaskClick(props.task.id.toString())
}
useEffect(() => {
if(props.channelId === props.task.id) {
setOpen(true)
setUnread(false)
}
else {
setOpen(false)
}
}, [props.channelId, props.task.id])
useEffect(() => {
joinOrCreate()
}, [joinOrCreate])
useEffect(() => {
if(channel.lastConsumedMessageIndex < lastMessage.index && !open) {
setUnread(true)
}
}, [channel.lastConsumedMessageIndex, lastMessage, open])
return (
<Row key={props.task.id} >
<Col className='justify-center'>
<Card className={'more-than-90 ' + (open? 'background-active' : null)}
onClick={e => onTaskSelect()}
>
<Row>
<Col md={2} style={{alignSelf: 'center', paddingLeft:'15px'}}>
{
props.task.worker.pic_url === "" || props.task.worker.pic_url === null ?
<div className="name-image">
{props.task.worker.first_name[0] + props.task.worker.last_name[0]}
</div>
:
<Image width={50} height={50} src={props.task.worker.pic_url} roundedCircle />
}
</Col>
<Col md={10}>
<Row>
<Col md={8}>
<p style={{fontSize:'.9rem'}}>{props.task.worker.name}</p>
</Col>
<Col>
<p style={{fontSize:'.7rem'}} className='left-align-text'>{lastMessage.time? moment(lastMessage.time).format('hh:mm A') : null}</p>
</Col>
</Row>
<Row>
<Col md={8}>
<p style={{fontSize:'.7rem'}}>{lastMessage.body? lastMessage.body : null}</p>
</Col>
<Col>
{
unread ?
<FontAwesomeIcon
icon={faEnvelopeOpenText}
size="lg"
color={"#0064bb"}
/>
:
null
}
</Col>
</Row>
</Col>
</Row>
</Card>
</Col>
</Row>
)
}
Twilio 開發人員布道師在這里。
我認為 Will Sams 的評論很有道理。 您確實需要設置一個未讀索引以使通道開始,然后才能具有有效的未讀索引。 從文檔:
注意:聊天不會自動設置消費范圍。 如果您未在應用程序中明確設置此選項,則通道內的用戶將不存在消費范圍。 如果沒有消耗范圍,您的用戶的消耗范圍(讀取狀態)將無法在客戶端之間正確同步。 如果用戶沒有在頻道上設置消費范圍,則獲取未消費的消息將始終返回 0 。 如果 Channel 的成員沒有消費狀態,則他們的最后消費索引和時間戳將為 null 或 0,具體取決於平台。
因此,在創建頻道時,我會將頻道的消息設置為未使用以啟動該措施。 您還可以使用 function setAllMessagesConsumed
而不必讀取最后一條消息的索引。
我還注意到,當您設置最后一條消息時,您錯過了在某一點設置其索引:
const recent_message = messages.items[messages.items.length - 1]
setLastMessage({
body: recent_message.body,
time: recent_message.timestamp,
})
這可能會造成麻煩。
我擔心你的回調和效果的設置方式。 當您觸發onTaskSelect
時,它看起來好像您將任務 ID 發送回父級。
props.onTaskClick(props.task.id.toString());
大概是這樣您就可以在主面板中看到所有消息。
但是,我還假設這會在父級中設置一個任務,然后將其作為props.tasks
傳遞給該子級。 當props.task.id
更新並且useEffect
以joinOrCreate
更改為前提時, joinOrCreate
回調設置為更新。 所以我的猜測是,每當您在任務之間進行更改時,都會觸發joinOrCreate
的清理和重新評估。 除了沒有清理 function 之外,因此您最終每次都為這些組件中的每一個重新加載通道。 我猜想這與破壞事件以及再次單擊時出現的最終錯誤有關。
相反,我可能會重新設計它,以便TaskCard
組件不控制通道 object 的生命周期。 我將加載並加入您打算在父組件中渲染的頻道列表,然后將頻道 object 傳遞給TaskCard
。 這將簡化組件,因為父級將處理數據,而TaskCard
可以只處理渲染。 這也意味着當卡片的狀態發生變化(從顯示到不顯示)時,您只是重新渲染數據。 這樣,您還可以在任務卡和屏幕截圖右側的聊天視圖之間共享頻道TaskCard
(否則我猜您也必須在該組件中加載它,這可能也無濟於事)。
這些只是基於我在您的應用程序中看到的一些想法。 我希望他們有所幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.