我的应用程序是用C#和ASP.NET开发的LiveChat
我有一个客户端计时器,它每秒调用webservice函数RetrieveMessages()。 此外,在用户发送消息后不久,我将调用相同的函数RetrieveMessages()。
我有一个存储最后一条消息Id的变量,因此,每个RetrieveMessage调用只检索未读的消息。
有时客户端会显示相同的消息两次,如下所示:
埃沃顿(14:22:20):你好! 埃弗顿(14:22:20):你好!双重性只发生在客户端,DataBase表没问题,没有重复。
我怀疑是Timer,发送消息正在更新变量lastMessageId之前执行RetrieveMessage。
如何同步RetrieveMessage()的调用?
以下是一些分析代码。
// ThisFunction is a callback that RetrieveMessage every time the user send's a message
function SendMessageSucess(cdMsgEnviada) {
//Carrega Mensagens
Avalon.Services.ChatService.RetrieveMessages(CodChamado, IdLastMsg, RetrieveMessagesSucess);
}
OnTImer Tick
// Every second, verify is exist new messages
function timer_onTick() {
//Carrega Mensagens
Avalon.Services.ChatService.RetrieveMessages(CodChamado, IdLastMsg, RetrieveMessagesSucess);
}
RetrieveMessages功能
function RetrieveMessagesSucess(result) {
var myMsgs = new Array();
for (var i = 0; i < result.length; i++) {
var obj = eval('(' + result[i] + ')');
if (obj != null)
myMsgs[i] = obj;
}
for (var j = 0; j < myMsgs.length; j++) {
if (myMsgs.length > 0) {
// Armazeno o codigo da ultima mensagem recebida
IdLastMsg = myMsgs[myMsgs.length - 1].cd_chat_message;
if (par) {
var novoconteudo = "<div style='background-color: #EFEFEF; padding: 10px;'>"
par = false;
}
else {
var novoconteudo = "<div style='padding: 10px;'>"
par = true;
}
if (myMsgs[j].origem_mensagem == 1) // Msg enviada pelo cliente
novoconteudo = novoconteudo + "<b>" + myMsgs[j].solicitante + ": </b>"
else
novoconteudo = novoconteudo + "<b>" + myMsgs[j].tecnico + ": </b>"
var objDate = eval(myMsgs[j].datahora.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
novoconteudo = novoconteudo + "(" + objDate.format("HH:MM:ss") + ") ";
novoconteudo = novoconteudo + myMsgs[j].texto + "</div>";
divChatHistory.append(novoconteudo);
AutoScroll();
if (myMsgs[j].origem_mensagem == 2) // Msg enviada por um tecnico
show_popAlert()
}
}
// Verifico se o chat esta ativo
IsChatInativo();
}
任何想法?
答案 0 :(得分:1)
尝试在输入tick方法时禁用计时器,并在离开方法之前重新启用它。
答案 1 :(得分:0)
设置一个对象的全局变量,并在向对话添加新消息时在其中创建新属性。在新属性的名称中使用您的消息ID,并将其设置为true或其他内容。如果您的每条消息都有唯一的ID,那么您可以在继续检查对象中是否存在该消息ID的特定属性之前验证您是否尚未处理该消息。
可能看起来像:
var PROCESSED_MSGS = new Object();
然后再......
for (var j = 0; j < myMsgs.length; j++) {
if (myMsgs.length > 0) {
thisMsgId = myMsgs[j].id;
if(PROCESSED_MSGS['msg'+thisMsgId]) continue;
PROCESSED_MSGS['msg'+thisMsgId] = true;
//keep going....
答案 2 :(得分:0)
Jage,您的解决方案运行正常。我在RetrieveMessages中做了一些调整 让我们看看代码:
function RetrieveMessagesSucess(result) {
// parsin the json and storing the messages in a array
var myMsgs = new Array();
for (var i = 0; i < result.length; i++) {
var obj = eval('(' + result[i] + ')');
if (obj != null)
myMsgs[i] = obj;
}
for (var j = 0; j < myMsgs.length; j++) {
if (myMsgs.length > 0) {
// Verifing if the message already exists
var divExiste = document.getElementById(myMsgs[j].cd_chat_message);
// If not exists, put the message on the page
if (divExiste == null) {
// Storing the id of tha last received message. This is useful as a parameter to retrieve messages again
IdLastMsg = myMsgs[myMsgs.length - 1].cd_chat_message;
// Trick to a zebra style
if (par) {
var novoconteudo = "<div id='" + myMsgs[j].cd_chat_message + "' style='background-color: #EFEFEF; padding: 10px;'>"
par = false;
}
else {
var novoconteudo = "<div id='" + myMsgs[j].cd_chat_message + "' style='padding: 10px;'>"
par = true;
}
// Putting the message on page
if (myMsgs[j].origem_mensagem == 1) // Msg enviada pelo cliente
novoconteudo = novoconteudo + "<b>" + myMsgs[j].solicitante + ": </b>"
else
novoconteudo = novoconteudo + "<b>" + myMsgs[j].tecnico + ": </b>"
var objDate = eval(myMsgs[j].datahora.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
novoconteudo = novoconteudo + "(" + objDate.format("HH:MM:ss") + ") ";
novoconteudo = novoconteudo + myMsgs[j].texto + "</div>";
divChatHistory.append(novoconteudo);
AutoScroll();
if (myMsgs[j].origem_mensagem == 2) // Msg enviada por um tecnico
show_popAlert()
}
}
}
IsChatInativo();
}
多数民众赞成。
非常感谢!
原谅我的英语不好= o)