我正在使用LCSK软件包,但有3个大问题。我是signalR的新手。
1-)问题是我的网站页面上有一个座席页面和聊天框。如果座席关闭页面并且此时有与客户聊天室。重新登录到座席页面后,我所有的聊天室都消失了,并且客户再次让我看不见,或者新用户如果他们对我怀念,我看不到他们对我怀念。
2-)问题是,如果用户更改页面并再次警告我,它将打开一个新的聊天室并为该用户设置新的ID
3-)问题是,如果座席关闭页面,用户和系统不知道我们处于离线状态,则它不关闭聊天框,或者不发送有关座席的离线或在线信息。
这是JS我的代码:
var myHub = $.connection.chatHub;
$(function () {
LCSKChat.config();
LCSKChat.init();
});
var LCSKChat = function () {
var chatKey = 'lcsk-chatId';
var requestChat = false;
var chatId = '';
var chatEditing = false;
var options = [];
function setDefaults() {options.width = 250;
options.offlineTitle = 'Mesaj Gönderin';
options.onlineTitle = 'Canlı Destek';
options.waitingForOperator = 'Lütfen bekleyiniz birazdan operator bağlanacaktır..';
options.emailSent = '<div style="color:green !important;" class="olark-form-message" data-reactid=".0.5.1.0">Mesajınız başarılı bir şekilde gönderilmiştir.</div>';
options.emailFailed = '<div style="color:red !important;" class="olark-form-message" data-reactid=".0.5.1.0">İletişim numarası zorunlu alandır.</div>';
}
function config(args) {
setDefaults();
if (args != null) {
for (key in options) {
if (args[key]) {
options[key] = args[key];
}
}
}
}
function getPlacement() {
if (options.placement == 'bottom-right') {
return 'bottom:0px;right:15px;';
}
return '';
}
function init() {
$('body').append(
//'<div id="chat-box-header" style="display: block;position:' + options.position + ';' + getPlacement() + 'width:' + options.width + 'px;padding:' + options.headerPaddings + ';color:' + options.headerTextColor + ';font-size:' + options.headerFontSize + ';cursor:pointer;background:' + options.headerBackgroundColor + ';filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'' + options.headerGradientStart + '\', endColorstr=\'' + options.headerGradientEnd + '\');background: -webkit-gradient(linear, left top, left bottom, from(' + options.headerGradientStart + '), to(' + options.headerGradientEnd + '));background: -moz-linear-gradient(top, ' + options.headerGradientStart + ', ' + options.headerGradientEnd + ');border:1px solid ' + options.headerBorderColor + ';box-shadow:inset 0 0 7px #0354cb;-webkit-box-shadow:inset 0 0 7px #0354cb;border-radius: 5px;">' + options.offlineTitle + '</div>' +
//'<div id="chat-box" style="display:none;position:' + options.position + ';' + getPlacement() + 'width:' + options.width + 'px;height:300px;padding: 10px 10px 10px 10px;border: 1px solid ' + options.boxBorderColor + ';background-color:' + options.boxBackgroundColor + ';font-size:small;"></div>'
'<div id="chat-box-header" style="line-height:25px;z-index:99999;text-align:center;height:25px;display: block;position:' + options.position + ';' + getPlacement() + 'width:' + options.width + 'px;padding:' + options.headerPaddings + ';color:' + options.headerTextColor + ';font-size:' + options.headerFontSize + ';cursor:pointer;background:' + options.headerBackgroundColor + ';filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'' + options.headerGradientStart + '\', endColorstr=\'' + options.headerGradientEnd + '\');background: -webkit-gradient(linear, left top, left bottom, from(' + options.headerGradientStart + '), to(' + options.headerGradientEnd + '));background: -moz-linear-gradient(top, ' + options.headerGradientStart + ', ' + options.headerGradientEnd + ');border:1px solid ' + options.headerBorderColor + ';box-shadow:inset 0 0 7px #5ba0d0;-webkit-box-shadow:inset 0 0 7px #5ba0d0;border-top-left-radius: 5px;border-top-right-radius: 5px;">' + "<svg class='chatBoxIcon pull-left' x='0px' y='0px' viewBox='0 0 28 18' aria-label='small picture of an envelope signifying email' role='img' data-reactid='.0.4.0'><title data-reactid='.0.4.0.0'>Envelope Icon</title><desc data-reactid='.0.4.0.1'>small picture of an envelope signifying email</desc><path='xx' fill='#ffffff' data-reactid='.0.4.0.2'></path></svg><div style='margin-right:24px'>" + options.offlineTitle + '</div></div>' +
'<div id="chat-box" style="z-index:99999;display:none;position:' + options.position + ';' + getPlacement() + 'width:' + options.width + 'px;height:300px;padding: 10px 10px 10px 10px;border: 1px solid ' + options.boxBorderColor + ';background-color:' + options.boxBackgroundColor + ';opacity: 0.8;font-size:14px !important;color: black !important;padding-top:14px !important;"></div>'
);
$.connection.hub.start()
.done(function () {
var existingChatId = getExistingChatId(chatKey);
$.get("http://ipinfo.io", function (response) {
myHub.server.logVisit(document.location.href, document.referrer, response.city, response.region, response.country, existingChatId);
}, "jsonp");
})
.fail(function () { chatRefreshState(false); });
$('body').on({
click: function () {
toggleChatBox();
}
}, '#chat-box-header');
$('#chat-box').on({
keydown: function (e) {
var msg = $(this).val();
if (e.keyCode == 13 && msg != '') {
e.preventDefault();
e.stopPropagation();
if (chatId == null || chatId == '') {
myHub.server.requestChat(msg);
$('#chat-box-msg').html(options.waitingForOperator);
} else {
myHub.server.send(msg);
}
$('#chat-box-textinput').val('');
}
}
}, '#chat-box-textinput');
$('#chat-box').on({
keydown: function () {
chatEditing = true;
}
}, '.chat-editing');
$('#chat-box').on({
click: function () {
// myHub.server.sendEmail($('#chat-box-email').val(), $('#chat-box-cmt').val());
if ($.trim($("#chat-box-email").val()) == "") {
$('#chat-box').html(options.emailFailed);
setTimeout(function () {
chatRefreshState();
}, 4000);
} else {
$.ajax({
type: 'POST',
cache: false,
url: '../apps/ashx/SendMessage.ashx',
data: { nameParam: ' ', phoneParam: $("#chat-box-email").val(), emailParam: ' ', msjParam: $("#chat-box-cmt").val() },
success: function (data) {
var jsonData = JSON.parse(data);
if (jsonData != null) {
if (jsonData.SuccessMessage != null && jsonData.SuccessMessage != "") {
$('#chat-box').html(options.emailSent);
setTimeout(function () {
chatRefreshState();
}, 5500);
}
if (jsonData.ErrorMessage != null && jsonData.ErrorMessage != "") {
$('#chat-box').html(options.emailFailed);
setTimeout(function () {
chatRefreshState();
}, 3000);
}
} else {
$('#chat-box').html(options.emailFailed);
setTimeout(function () {
chatRefreshState();
}, 3000);
}
},
error: function (xhr, ajaxOptions, thrownError) {
$('#chat-box').html(options.emailFailed);
setTimeout(function () {
chatRefreshState();
}, 3000);
}
});
}
chatEditing = false;
}
}, '#chat-box-send');
}
function chatRefreshState(state) {
if (state) {
$('#chat-box-header').html("<svg class='chatBoxIcon pull-left' viewBox='0 0 20 20'><path d='xxx'></path></svg><div style='margin-right:24px'>" + options.onlineTitle + "</div>");
if (!requestChat) {
$('#chat-box').html(
'<div id="chat-box-msg" style="height:265px;overflow:auto;">' +
'<p>Sorularınızı Bekliyoruz!</p><p>En uygun , en profesyonel kurum sohbet hattındasınız.</p></div>' +
'<div id="chat-box-input" style="height:35px;margin-right:13px;"><textarea id="chat-box-textinput" style="width:100%;height: 32px;border:1px solid #0354cb;border-radius: 3px;" /></div>'
);
}
} else {
if (!chatEditing) {
$('#chat-box-header').html("<svg class='chatBoxIcon pull-left' x='0px' y='0px' viewBox='0 0 28 18' aria-label='small picture of an envelope signifying email' role='img' data-reactid='.0.4.0'><title data-reactid='.0.4.0.0'>Envelope Icon</title><desc data-reactid='.0.4.0.1'>small picture of an envelope signifying email</desc><path fill='#ffffff' d='M28,3.2C28,1.5,26.5,0,24.8,0H3.2C1.5,0,0,1.5,0,3.2v11.5C0,16.5,1.5,18,3.2,18h21.5c1.8,0,3.2-1.5,3.2-3.2 V3.2z M24.7,14.8c-0.2,0.1-0.4,0.2-0.6,0.2c-0.2,0-0.4-0.1-0.6-0.3l-5-5.3l-3.6,3c-0.3,0.2-0.6,0.3-0.9,0.3s-0.7-0.1-0.9-0.4l-3.6-3 l-5,5.3c-0.2,0.2-0.4,0.3-0.6,0.3c-0.2,0-0.4-0.1-0.6-0.2c-0.3-0.3-0.4-0.8,0-1.2l4.9-5.3L3.3,4.5C3,4.2,2.9,3.6,3.2,3.3 C3.5,2.9,4,2.9,4.4,3.2l9.6,7.9l9.6-7.9c0.4-0.3,0.9-0.2,1.2,0.1c0.3,0.4,0.2,0.9-0.1,1.2l-4.8,3.9l4.9,5.3 C25.1,14,25,14.5,24.7,14.8z' data-reactid='.0.4.0.2'></path></svg><div style='margin-right:24px'>" + options.offlineTitle + "</div>");
$('#chat-box-input').hide();
$('#chat-box').html(
"<div class='olark-form-message' data-reactid='.0.5.1.0'>Aynı gün dönüş garantisi ile.</div>" +
"<p style='margin-bottom:3px;'>İletişim No</p><input type='text' id='chat-box-email' style='border:1px solid #0354cb;border-radius: 3px;width: 94%;' class='chat-editing' />" +
'<p style="margin-bottom:3px !important;">Mesajınız</p><textarea placeholder="Mesajınızı buraya yazınız" id="chat-box-cmt" cols="40" rows="7" class="chat-editing" style="border:1px solid #0354cb;border-radius: 3px;width: 94% !important;"></textarea>' +
'<p><input style="height:44px;line-height:0" class="btn-block wpcf7-form-control wpcf7-submit btn btn-primary" type="button" id="chat-box-send" value="Mesaj Gönder " />'
);
}
}
}
function toggleChatBox() {
var elm = $('#chat-box-header');
if ($('#chat-box').hasClass('chat-open')) {
$('#chat-box').removeClass('chat-open');
elm.css('bottom', '0px');
} else {
var y = 301 + elm.height();
$('#chat-box').addClass('chat-open');
elm.css('bottom', y);
}
$('#chat-box').slideToggle();
}
function hasStorage() {
return typeof (Storage) !== 'undefined';
}
function setChatId(chatId) {
if (hasStorage()) {
sessionStorage.setItem(chatKey, chatId);
}
}
function getExistingChatId() {
if (hasStorage()) {
return sessionStorage.getItem(chatKey);
}
}
myHub.client.setChat = function (id, agentName, existing) {
chatId = id;
requestChat = true;
setChatId(chatId);
if (existing) {
if (!$('#chat-box').hasClass('chat-open')) {
toggleChatBox();
}
$('#chat-box-msg').append('<p><strong> Canlı Destek</strong>, Buyrun nasıl yardımcı olabiliriz.</p>');
} else {
$('#chat-box-msg').append('<p><strong>Sohbet Başladı</strong></p>');
}
};
myHub.client.addMessage = function (from, msg) {
if (chatId != null && chatId != '') {
if (!requestChat) {
if (!$('#chat-box').hasClass('chat-open')) {
toggleChatBox();
}
requestChat = true;
}
//if (from=='me') {
// from = 'Ben';
//}
//if (from == 'admin') {
// from = 'Canlı Destek';
//}
$('#chat-box-msg').append('<p><strong>' + from + '</strong>: ' + msg + '</p>');
if (from == '') {
chatId = '';
requestChat = false;
}
$("#chat-box-msg").scrollTop($("#chat-box-msg")[0].scrollHeight);
}
}
myHub.client.emailResult = function (state) {
//if (!state) {
// $('#chat-box').html(options.emailFailed);
//}
};
myHub.client.onlineStatus = function (state) {
chatRefreshState(state);
};
return {
config: config,
init: init
}
}();
这是我的ChatHub:
private static ConcurrentDictionary<string, Agent> Agents;
private static ConcurrentDictionary<string, string> ChatSessions;
public void AgentConnect(string name, string pass)
{
if (Agents == null)
Agents = new ConcurrentDictionary<string, Agent>();
if (ChatSessions == null)
ChatSessions = new ConcurrentDictionary<string, string>();
string hashPass = ToHash(pass);
var config = GetConfig();
if (config == null || config.Length < 2)
{
Clients.Caller.loginResult(false, "config", "");
}
else if ((config[0] == hashPass) || (config[1] == hashPass))
{
var agent = new Agent()
{
Id = Context.ConnectionId,
Name = name,
IsOnline = true
};
// if the agent is already signed-in
if(Agents.Any(x => x.Key == name))
{
agent = Agents[name];
Clients.Caller.loginResult(true, agent.Id, agent.Name);
Clients.All.onlineStatus(Agents.Count(x => x.Value.IsOnline) > 0);
}
else if (Agents.TryAdd(name, agent))
{
Clients.Caller.loginResult(true, agent.Id, agent.Name);
Clients.All.onlineStatus(Agents.Count(x => x.Value.IsOnline) > 0);
}
else
{
Clients.Caller.loginResult(false, "error", "");
}
}
else
Clients.Caller.loginResult(false, "pass", "");
}
public void ChangeStatus(bool online)
{
var agent = Agents.SingleOrDefault(x => x.Value.Id == Context.ConnectionId).Value;
if (agent != null)
{
agent.IsOnline = online;
// TODO: Check if the agent was in chat sessions.
Clients.All.onlineStatus(Agents.Count(x => x.Value.IsOnline) > 0);
}
}
public void EngageVisitor(string connectionId)
{
var agent = Agents.SingleOrDefault(x => x.Value.Id == Context.ConnectionId).Value;
if(agent != null)
{
ChatSessions.TryAdd(connectionId, agent.Id);
Clients.Caller.newChat(connectionId);
Clients.Client(connectionId).setChat(connectionId, agent.Name, false);
Clients.Caller.addMessage(connectionId, "Sistem", "Kullanıcıyı sohbeti çağırdınız");
Clients.Client(connectionId).addMessage(agent.Name, "Merhaba. Ben " + agent.Name + " size nasıl yardımcı olabilirim.");
}
}
public void LogVisit(string page, string referrer, string city, string region, string country, string existingChatId)
{
if (Agents == null)
Agents = new ConcurrentDictionary<string, Agent>();
Clients.Caller.onlineStatus(Agents.Count(x => x.Value.IsOnline) > 0);
var cityDisplayName = GetCityDisplayName(city, region);
var countryDisplayName = country ?? string.Empty;
if (!string.IsNullOrEmpty(existingChatId) &&
ChatSessions.ContainsKey(existingChatId))
{
var agentId = ChatSessions[existingChatId];
Clients.Client(agentId).visitorSwitchPage(existingChatId, Context.ConnectionId, page);
var agent = Agents.SingleOrDefault(x => x.Value.Id == agentId).Value;
if (agent != null)
Clients.Caller.setChat(Context.ConnectionId, agent.Name, true);
string buffer = "";
ChatSessions.TryRemove(existingChatId, out buffer);
ChatSessions.TryAdd(Context.ConnectionId, agentId);
}
foreach (var agent in Agents)
{
var chatWith = (from c in ChatSessions
join a in Agents on c.Value equals a.Value.Id
where c.Key == Context.ConnectionId
select a.Value.Name).SingleOrDefault();
Clients.Client(agent.Value.Id).newVisit(page, referrer, cityDisplayName, countryDisplayName, chatWith, Context.ConnectionId);
}
}
public void RequestChat(string message)
{
// We assign the chat to the less buzy agent
var workload = from a in Agents
where a.Value.IsOnline
select new
{
Id = a.Value.Id,
Name = a.Value.Name,
Count = ChatSessions.Count(x => x.Value == a.Value.Id)
};
if (workload == null)
{
Clients.Caller.addMessage("", "Cevrımdışıyız.");
return;
}
var lessBuzy = workload.OrderBy(x => x.Count).FirstOrDefault();
if (lessBuzy == null)
{
Clients.Caller.addMessage("", "Cevrımdışıyız.");
return;
}
ChatSessions.TryAdd(Context.ConnectionId, lessBuzy.Id);
Clients.Client(lessBuzy.Id).newChat(Context.ConnectionId);
Clients.Caller.setChat(Context.ConnectionId, lessBuzy.Name, false);
Clients.Client(lessBuzy.Id).addMessage(Context.ConnectionId, "visitor", message);
Clients.Caller.addMessage("me", message);
}
public void Transfer(string connectionId, string agentName, string messages)
{
if(!Agents.ContainsKey(agentName))
{
Clients.Caller.addMessage(Context.ConnectionId, "system", "This agent does not exists: " + agentName);
return;
}
var agent = Agents[agentName];
if(!agent.IsOnline)
{
Clients.Caller.addMessage(Context.ConnectionId, "system", agentName + " is not online at the moment.");
return;
}
if(!ChatSessions.ContainsKey(connectionId))
{
Clients.Caller.addMessage(Context.ConnectionId, "system", "Kullanıcı artık sayfada bulunmuyor.");
return;
}
string currentAgentId = "";
if (ChatSessions.TryRemove(connectionId, out currentAgentId) &&
ChatSessions.TryAdd(connectionId, agent.Id))
{
Clients.Client(agent.Id).newChat(connectionId);
Clients.Client(agent.Id).addMessage(connectionId, "system", "New chat transfered to you.");
Clients.Client(agent.Id).addMessage(connectionId, ">>", "Starting previous conversation");
Clients.Client(agent.Id).addMessage("", messages);
Clients.Client(agent.Id).addMessage(connectionId, "<<", "End of previous conversation");
Clients.Client(connectionId).addMessage("", "You have been transfered to " + agent.Name);
Clients.Client(connectionId).setChat(connectionId, agent.Name, true);
Clients.Caller.addMessage(connectionId, "system", "Chat transfered to " + agentName);
}
}
public void Send(string data)
{
Clients.Caller.addMessage("me", data);
if (ChatSessions.ContainsKey(Context.ConnectionId))
{
var opId = ChatSessions[Context.ConnectionId];
Clients.Client(opId).addMessage(Context.ConnectionId, "visitor", data);
}
else
{
Debug.WriteLine("Chat Session not found.");
// refactor this
var workload = from a in Agents
where a.Value.IsOnline
select new
{
Id = a.Value.Id,
Name = a.Value.Name,
Count = ChatSessions.Count(x => x.Value == a.Value.Id)
};
if (workload == null)
{
Clients.Caller.addMessage("", "Çevrimdışıyız.");
return;
}
var lessBuzy = workload.OrderBy(x => x.Count).FirstOrDefault();
if (lessBuzy == null)
{
Clients.Caller.addMessage("", "Çevrimdışıyız.");
return;
}
ChatSessions.TryAdd(Context.ConnectionId, lessBuzy.Id);
Clients.Client(lessBuzy.Id).newChat(Context.ConnectionId);
Clients.Caller.setChat(Context.ConnectionId, lessBuzy.Name, false);
Clients.Client(lessBuzy.Id).addMessage(Context.ConnectionId, "system", "This visitor appear to have lost their chat session.");
Clients.Client(lessBuzy.Id).addMessage(Context.ConnectionId, "visitor", data);
}
}
public void OpSend(string id, string data)
{
var agent = Agents.SingleOrDefault(x => x.Value.Id == Context.ConnectionId).Value;
if (agent == null)
{
Clients.Caller.addMessage(id, "system", "Mesajımız size iletilirken sorun yaşıyoruz.Lütfen refreshleyiniz sayfanızı");
return;
}
if (id == "internal")
{
foreach (var a in Agents.Where(x => x.Value.IsOnline))
Clients.Client(a.Value.Id).addMessage(id, agent.Name, data);
}
else if (ChatSessions.ContainsKey(id))
{
Clients.Caller.addMessage(id, "you", data);
Clients.Client(id).addMessage(agent.Name, data);
}
}
public void CloseChat(string id)
{
if (ChatSessions.ContainsKey(id))
{
//canlı destek konusma penceresini kaparsa karsı tarafa gidicek mesaj
Clients.Client(id).addMessage("", "Sohbet kapatıldı.");
string buffer = "";
ChatSessions.TryRemove(id, out buffer);
}
}
public void LeaveChat(string id)
{
// was it an agent
var agent = Agents.SingleOrDefault(x => x.Value.Id == id).Value;
if (agent != null)
{
Agent tmp = null;
if (Agents.TryRemove(agent.Name, out tmp))
{
var sessions = ChatSessions.Where(x => x.Value == agent.Id);
if (sessions != null)
{
foreach (var session in sessions)
Clients.Client(session.Key).addMessage("", "Tekrar bağlanılıyor...");
}
Clients.All.updateStatus(Agents.Count(x => x.Value.IsOnline) > 0);
}
}
// was it a visitor
if (ChatSessions.ContainsKey(id))
{
var agentId = ChatSessions[id];
Clients.Client(agentId).addMessage(id, "Sistem", "Misafir sohbeti kapattı");
}
}
public override Task OnDisconnected(bool stopCalled)
{
return Clients.All.leave(Context.ConnectionId);
}
public void SendEmail(string from, string message)
{
var msg = new MailMessage();
msg.To.Add(new MailAddress(from));
msg.Subject = "LCSK - Offline Contact";
msg.Body = "You received an offline contact from your LCSK chat widget.\r\n\r\n" + message;
using (var client = new SmtpClient())
{
client.Send(msg);
}
}
#region Install and config methods
public void getInstallState()
{
var config = GetConfig();
if (config != null && config.Length >= 2)
Clients.Caller.installState(true, config[0]);
else
Clients.Caller.installState(false, "lcskv2hctemptoken");
}
public void AdminRequest(string pass)
{
var config = GetConfig();
if (config != null && config.Length >= 2)
{
if (config[0] == ToHash(pass))
Clients.Caller.adminResult(true, config[0]);
else
Clients.Caller.adminResult(false, "");
}
else
Clients.Caller.adminResult(false, "");
}
public void SetConfig(string token, string adminPass, string agentPass)
{
bool shouldSave = false;
var config = GetConfig();
if (config != null && config.Length >= 2)
{
if (config[0] == token)
shouldSave = true;
}
if (token == "lcskv2hctemptoken")
shouldSave = true;
if (shouldSave)
{
string configPath = HttpContext.Current.Server.MapPath("~/App_Data/" + CONFIG_FILE);
File.WriteAllText(
configPath,
ToHash(adminPass) + "\n" + ToHash(agentPass));
Clients.Caller.setConfigResult(true, "Config güncellendi");
}
else
Clients.Caller.setConfigResult(false, "Kaydederken bir sorun oluştu.");
}
private string GetCityDisplayName(string city, string region)
{
var displayCity = string.Empty;
if (!string.IsNullOrEmpty(city))
{
displayCity = city;
if (!string.IsNullOrEmpty(region))
{
displayCity += ", " + region;
}
}
return displayCity;
}
private string[] GetConfig()
{
string configPath = HttpContext.Current.Server.MapPath("~/App_Data/" + CONFIG_FILE);
if (File.Exists(configPath))
{
return File.ReadAllLines(configPath);
}
return null;
}
public string ToHash(string password)
{
if (string.IsNullOrEmpty(password))
return "";
var provider = new SHA1CryptoServiceProvider();
var encoding = new UnicodeEncoding();
return Convert.ToBase64String(provider.ComputeHash(encoding.GetBytes(password)));
}
#endregion