پشتیبانی آنلاین سایت با SignalR ،ASP.NET MVC و AngularJS
نویسنده: حسین حقیقیان
تاریخ: ۱۳۹۵/۰۲/۲۱ ۲۳:۳۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
//client Install-Package angularjs Install-Package angular-strap Install-Package Microsoft.AspNet.SignalR.JS install-package AngularJs.SignalR.Hub Install-Package jQuery.TimeAgo Install-Package FontAwesome Install-Package toastr Install-Package Twitter.Bootstrap.RTL bower install angular-smilies //server Install-Package Newtonsoft.Json Install-Package Microsoft.AspNet.SignalR Install-Package EntityFramework
public partial class Message
{
public int Id { get; set; }
public string Sender { get; set; }
public string Receiver { get; set; }
public string Body { get; set; }
public DateTimeOffset? CreationTime { get; set; }
public int? SessionId { get; set; }
public virtual Session Session { get; set; }
}
public partial class Session
{
public Session()
{
Messages = new List<Message>();
Sessions = new List<Session>();
}
public int Id { get; set; }
public string AgentName { get; set; }
public string CustomerName { get; set; }
public DateTime CreatedDateTime { get; set; }
public int? ParentId { get; set; }
public virtual Session Parent { get; set; }
public virtual ICollection<Message> Messages { get; set; }
public virtual ICollection<Session> Sessions { get; set; }
} public class UserInformation
{
public string ConnectionId { get; set; }
public bool IsOnline { get; set; }
public string UserName { get; set; }
}
public class ChatSessionVm
{
public string Key { get; set; }
public List<string> Value { get; set; }
}
public class AgentViewModel
{
public int Id { get; set; }
public string CustomerName { get; set; }
public int Lenght { get; set; }
public DateTimeOffset? Date { get; set; }
} [HubName("chatHub")]
public class ChatHub : Microsoft.AspNet.SignalR.Hub
{
} $scope.myHub = new hub("chatHub", {
listeners: {},
methods: []
}) $scope.myHub.promise.done(function () {
$scope.myHub.init();
$scope.myHub.promise.done(function () { });
}); public void Init()
{
_chatSessions = _chatSessions ?? (_chatSessions = new List<ChatSessionVm>());
_agents = _agents ?? (_agents = new ConcurrentDictionary<string, UserInformation>());
Clients.Caller.onlineStatus(_agents.Count(x => x.Value.IsOnline) > 0);
} $scope.requestChat = function (msg) {
if (!defaultCustomerUserName) {
//گرفتن کاربر لاگین شده
//ما از آرایه تصادفی استفاده میکنیم
var nameDefaultArray = [
'حسین', 'حسن', 'علی', 'عباس', 'زهرا', 'سمیه'
];
defaultCustomerUserName=nameDefaultArray[Math.floor(Math.random() * nameDefaultArray.length)];
}
var userName = defaultCustomerUserName;
if (!$scope.chatId) {
$scope.chatId = sessionStorage.getItem(chatKey);
$http.get("http://ipinfo.io")
.success(function (response) {
$scope.myHub.logVisit(response.city, response.country, msg, userName);
}).error(function (e, status, headers, config) {
$scope.myHub.logVisit("Tehran", "Ir", msg, userName)
});
$scope.myHub.requestChat(msg);
$scope.chatTitle = $scope.options.waitingForOperator;
$scope.pendingRequestChat = true;
} else {
$scope.myHub.clientSendMessage(msg, userName);
};
$scope.message = "";
}; public void AcceptRequestChat(string customerConnectionId, string body, string userName)
{
var agent = FindAgent(Context.ConnectionId);
var session = _chatSessions.FirstOrDefault(item => item.Key.Equals(agent.Key));
if (session == null)
{
_chatSessions.Add(new ChatSessionVm
{
Key = agent.Key,
Value = new List<string> { customerConnectionId }
});
}
else
{
session.Value.Add(customerConnectionId);
}
Clients.Client(Context.ConnectionId).agentChat(customerConnectionId, body, userName);
Clients.Client(customerConnectionId).clientChat(customerConnectionId, agent.Value.UserName);
foreach (var item in _agents.Where(item => item.Value.IsOnline))
{
Clients.Client(item.Value.ConnectionId).refreshChatWith(agent.Value.UserName, customerConnectionId);
}
var session = _db.Sessions.Add(new Session
{
AgentName = agent.Key,
CustomerName = userName,
CreatedDateTime = DateTime.Now
});
_db.SaveChanges();
var message = new Message
{
CreationTime = DateTime.Now,
Sender = agent.Key,
Receiver = userName,
body=body,
Session = session
};
_db.Messages.Add(message);
_db.SaveChanges();
} public void CloseChat(string id)
{
var findAgent = FindAgent(Context.ConnectionId);
var session = _chatSessions.FirstOrDefault(item => item.Value.Contains(id));
if (session == null) return;
Clients.Client(id).clientAddMessage(findAgent.Key, "مکالمه شما با کارشناس مربوطه به اتمام رسیده است");
foreach (var agent in _agents)
{
Clients.Client(agent.Value.ConnectionId).refreshLeaveChat(agent.Value.UserName, id);
}
_chatSessions.Remove(session);
} public void EngageVisitor(string newAgentId, string cumtomerId, string customerName,string clientSessionId)
{
#region remove session of current agent
var currentAgent = FindAgent(Context.ConnectionId);
var currentSession = _chatSessions.FirstOrDefault(item => item.Value.Contains(cumtomerId));
if (currentSession != null)
{
_chatSessions.Remove(currentSession);
}
#endregion
#region add session to new agent
var newAgent = FindAgent(newAgentId);
var newSession = _chatSessions.FirstOrDefault(item => item.Key.Equals(newAgent.Key));
if (newSession == null)
{
_chatSessions.Add(new ChatSessionVm
{
Key = newAgent.Key,
Value = new List<string> { cumtomerId }
});
}
else
{
newSession.Value.Add(cumtomerId);
}
#endregion
Clients.Client(currentAgent.Value.ConnectionId).addMessage(cumtomerId, newAgent.Key,
"ادامه مکالمه به کارشناس " + newAgent.Key + "مقابل منتقل شد");
Clients.Client(newAgentId).addMessage(cumtomerId, currentAgent.Key,
"لطفا مکالمه را ادامه دهید.با تشکر");
Clients.Client(cumtomerId).clientAddMessage(newAgent.Value.UserName,
"مکالمه شما با کارشناس زیر برقرار گردید" + newAgent.Key);
var session = _db.Sessions.FirstOrDefault
(item => item.AgentName.Equals(currentAgent.Value.UserName)
&& item.CustomerName.Equals(customerName));
if (session != null)
{
var sessionId = session.Id;
var messages = _db.Messages.Where(item => item.Session.Id.Equals(sessionId));
var result = JsonConvert.SerializeObject(messages, new Formatting(), _settings);
Clients.Client(newAgentId).visitorSwitchConversation
(Context.ConnectionId, customerName, result, clientSessionId);
}
foreach (var item in _agents.Where(item => item.Value.IsOnline))
{
Clients.Client(item.Value.ConnectionId).refreshChatWith(newAgent.Value.UserName, cumtomerId);
}
_db.Sessions.Add(new Session
{
AgentName = newAgent.Key,
CustomerName = customerName,
CreatedDateTime = DateTime.Now,
Parent = _db.Sessions.Where(item => item.AgentName.Equals(currentAgent.Key)
&& item.CustomerName.Equals(customerName)).OrderByDescending(item => item.Id).FirstOrDefault()
});
_db.SaveChanges();
} var app = angular.module("app", ["SignalR", 'ngRoute', 'ngAnimate', 'ngSanitize', 'mgcrea.ngStrap', 'angular-smilies']);
app.config(["$routeProvider", "$provide", "$httpProvider", "$locationProvider",
function ($routeProvider, $provide, $httpProvider, $locationProvider) {
$routeProvider.
when('/', { templateUrl: 'app/views/home.html', controller: "HomeCtrl" }).
when('/agent', { templateUrl: 'app/views/agent.html', controller: "ChatCtrl" })
.otherwise({
redirectTo: "/"
});;
}]);
app.controller("HomeCtrl", ["$scope", function ($scope) {
$scope.title = "home";
}])
app.controller("ChatCtrl", ["$scope", "Hub", "$location", "$http", "$rootScope",
function ($scope, hub, $location, $http, $rootScope) {
if (!$scope.myHub) {
var chatKey = "angular-signalr";
var defaultCustomerUserName = null;
function getid(id) {
var find = false;
var position = null;
angular.forEach($scope.chatConversation, function (index, i) {
if (index.id === id && !find) {
find = true;
position = i;
return;
}
});
return position;
}
function apply() {
$scope.$apply();
}
$scope.boxheader = function () {
var height = 0;
$("#chat-box").slideToggle('slow', function () {
if ($("#chat-box-header").css("bottom") === "0px") {
height = $("#chat-box").height() + 20;
} else {
height = 0;
}
$("#chat-box-header").css("bottom", height);
});
};
var init = function () {
$scope.agent = {
id: "", name: "", isOnline: false
};
$rootScope.msg = "";
$scope.alarmStatus = false;
$scope.options = {
offlineTitle: "آفلاین",
onlineTitle: "آنلاین",
waitingForOperator: "لطفا منتظر بمانید تا به اپراتور وصل شوید",
emailSent: "ایمیل ارسال گردید",
emailFailed: "متاسفانه ایمیل ارسال نگردید",
logOut: "خروج",
setting: "تنظیمات",
conversion: "آرشیو",
edit: "ویرایش",
alarm: "قطع/وصل کردن صدا",
complete: "تکمیل",
pending: "منتظر ماندن",
reject: "عدم پذیرش",
lock: "آنلاین شدن",
unlock: "آفلاین شدن",
alarmOn: "روشن",
alarmOff: "خاموش",
upload: "آپلود"
};
$scope.chatConversation = [];
$scope.chatSessions = [];
$scope.customerVisit = [];
$scope.agentClientMsgs = [];
$scope.clientAgentMsg = [];
}();
//تعریف هاب به همراه متدهای آن
$scope.myHub = new hub("chatHub", {
listeners: {
"clientChat": function (id, agentName) {
$scope.clientAgentMsg.push({ name: agentName, msg: "با سلام در خدمت میباشم" });
$scope.chatTitle = "کارشناس: " + agentName;
$scope.pendingRequestChat = false;
sessionStorage.setItem(chatKey, id);
}, "agentChat": function (id, firstComment, customerName) {
var date = new Date();
var position = getid(id);
if (position > 0) {
$scope.chatSessions[position].length = $scope.chatConversation[position].length + 1;
$scope.chatSessions[position].date = date.toISOString();
return;
}
else {
$scope.chatConversation.push({
id: id,
sessions: [{
name: customerName,
msg: firstComment,
date: date
}],
agentName: $scope.agent.name,
customerName: customerName,
dateStartChat: date.getHours() + ":" + date.getMinutes(),
});
$scope.chatSessions.push({
id: id,
length: 1,
userName: customerName,
date: date.toISOString()
});
}
sessionStorage.setItem(chatKey, id);
apply();
},
//برروز رسانی لیست برای کارشناسان
"refreshChatWith": function (agentName, customerConnectionId) {
angular.forEach($scope.customerVisit, function (index, i) {
if (index.connectionId === customerConnectionId) {
$scope.customerVisit[i].chatWith = agentName;
}
});
apply();
},
//برروز رسانی لیست برای کارشناسان
"refreshLeaveChat": function (agentName, customerConnectionId) {
angular.forEach($scope.customerVisit, function (index, i) {
if (index.connectionId === customerConnectionId) {
$scope.customerVisit[i].chatWith =agentName + "---" + " به مکالمه خاتمه داده است ";
}
});
apply();
}
//وضعیت آنلاین بودن کارشناسان
, "onlineStatus": function (state) {
if (state) {
$scope.chatTitle = $scope.options.onlineTitle;
$scope.hasOnline = true;
$scope.hasOffline = false;
} else {
$scope.chatTitle = $scope.options.offlineTitle;
$scope.hasOffline = true;
$scope.hasOnline = false;
}
$scope.$apply()
}, "loginResult": function (status, id, name) {
if (status) {
$scope.agent.id = id;
$scope.agent.name = name;
$scope.agent.isOnline = true;
$scope.userIsLogin = $scope.agent;
$scope.$apply(function () {
$location.path("/agent");
});
} else {
$scope.agent = null;
toastr.error("کارشناسی با این مشخصات وجود ندارد");
return;
}
}, "newVisit": function (userName, city, country, chatWith, connectionId, firstComment) {
var exist = false;
angular.forEach($scope.customerVisit, function (index) {
if (index.connectionId === connectionId) {
exist = true;
return;
}
});
if (!exist) {
var date = new Date();
$scope.customerVisit.unshift({
userName: userName,
date: date,
city: city,
country: country,
chatWith: chatWith,
connectionId: connectionId,
firstComment: firstComment
});
if ($scope.alarmStatus) {
var snd = new Audio("/App/assets/sounds/Sedna.ogg");
snd.play();
}
toastr.success("تقاضای جدید دریافت گردید");
apply();
}
}, "addMessage": function (id, from, value) {
if ($scope.alarmStatus) {
var snd = new Audio("/App/assets/sounds/newmsg.mp3");
snd.play();
}
$scope.agentUserMsgs = [];
var date = new Date();
var position = getid(id);
if ($scope.chatConversation.length > 0 && position != null) {
$scope.chatConversation[position].sessions.push({ name: from, msg: value, date: date });
}
var item = $scope.chatConversation[position];
if (item) {
angular.forEach(item.sessions, function (index) {
$scope.agentUserMsgs.push({ name: index.name, msg: index.msg, date: date });
});
$scope.chatSessions[position].length = $scope.chatSessions[position].length + 1;
}
apply();
}, "clientAddMessage": function (id, from) {
if ($scope.alarmStatus) {
var snd = new Audio("/App/assets/sounds/newmsg.mp3");
snd.play();
}
$scope.clientAgentMsg.push({ name: id, msg: from });
apply();
}, "visitorSwitchConversation": function (id, customerName, sessions, sessionId) {
sessions = JSON.parse(sessions);
var date = new Date();
var sessionList = [];
angular.forEach(sessions, function (index) {
sessionList.push({
name: index.sender,
msg: index.body,
date: index.creationTime
});
});
$scope.chatConversation.push({
id: sessionId,
sessions: sessionList,
customerName: customerName,
dateStartChat: date.getHours() + ":" + date.getMinutes(),
agentName: $scope.agent.name
});
$scope.chatSessions.push({
id: sessionId,
length: sessions.length,
date: date
});
}, "receiveTicket": function (items) {
angular.forEach(JSON.parse(items), function (index) {
$scope.ticketList = [];
$scope.ticketList.push(index);
});
},
//آرشیو گفته گوهای کارشناس
"receiveHistory": function (items) {
$scope.agentHistory = [];
angular.forEach(JSON.parse(items), function (index) {
$scope.agentHistory.push(index);
});
apply();
},
//جزییات آرشیو گفتگوها
"detailsHistory": function (items) {
$scope.historyMsg = [];
angular.forEach(JSON.parse(items), function (index) {
$scope.historyMsg.push({ name: index.sender, msg: index.body, date: index.creationTime });
});
$("#detailsAgentHistory").modal();
apply();
},
//لیست کارشناسان آنلاین
"agentList": function (items) {
$scope.agentList = [];
angular.forEach(items, function (index) {
if ($scope.agent.name != index.Key) {
$scope.agentList.push({ name: index.Key, id: index.Value.ConnectionId });
}
});
$("#agentList").modal();
apply();
}
},
methods: ["agentConnect", "sendTicket", "requestChat", "clientSendMessage", "closeChat", "init", "logVisit",
"agentChangeStatus", "engageVisitor", "agentSendMessage", "transfer", "leaveChat", "acceptRequestChat",
"leaveChat", "detailsSessoinMessage", "showAgentList", "getAgentHistoryChat"
], errorHandler: function (error) {
console.error(error);
}
});
$scope.myHub.promise.done(function () {
$scope.myHub.init();
$scope.myHub.promise.done(function () { });
});
$scope.LeaveChat = function () {
$scope.myHub.LeaveChat();
};
$scope.loginAgent = function (userName) {
// username :security user username from agent role
if (userName == "hossein" || userName == "ali") {
$scope.myHub.promise.done(function () {
$scope.myHub.agentConnect(userName).then(function (result) {
$scope.agent.name = userName;
$scope.agent.isOnline = true;
});
});
}
};
$scope.requestChat = function (msg) {
if (!defaultCustomerUserName) {
//گرفتن کاربر لاگین شده
//ما از آرایه تصادفی استفاده میکنیم
var nameDefaultArray = [
'حسین', 'حسن', 'علی', 'عباس', 'زهرا', 'سمیه'
];
defaultCustomerUserName=nameDefaultArray[Math.floor(Math.random() * nameDefaultArray.length)];
}
var userName = defaultCustomerUserName;
if (!$scope.chatId) {
$scope.chatId = sessionStorage.getItem(chatKey);
$http.get("http://ipinfo.io")
.success(function (response) {
$scope.myHub.logVisit(response.city, response.country, msg, userName);
}).error(function (e, status, headers, config) {
$scope.myHub.logVisit("Tehran", "Ir", msg, userName)
});
$scope.myHub.requestChat(msg);
$scope.chatTitle = $scope.options.waitingForOperator;
$scope.pendingRequestChat = true;
} else {
$scope.myHub.clientSendMessage(msg, userName);
};
$scope.message = "";
};
$scope.acceptRequestChat = function (customerConnectionId, firstComment, customerName) {
$scope.myHub.acceptRequestChat(customerConnectionId, firstComment, customerName);
};
$scope.changeAgentStatus = function () {
$scope.agent.isOnline = !$scope.agent.isOnline;
$scope.myHub.agentChangeStatus($scope.agent.isOnline);
};
$scope.detailsChat = function (chatId, userName) {
$scope.agentUserMsgs = [];
angular.forEach($scope.chatConversation, function (index) {
if (index.id === chatId) {
$scope.dateStartChat = index.dateStartChat;
angular.forEach(index.sessions, function (value) {
$scope.agentUserMsgs.push({ name: value.name, msg: value.msg, date: value.date });
});
};
});
$scope.agentChatWithUser = chatId;
$scope.customerName = userName;
$("#agentUserChat").modal();
};
$scope.ticket = {
submit: function () {
var name = $scope.ticket.name;
var email = $scope.ticket.email;
var comment = $scope.ticket.comment;
$scope.myHub.sendTicket(name, email, comment);
}
};
$scope.showHistory = function () {
$scope.myHub.getAgentHistoryChat($scope.agent.name);
};
$scope.detailsChatHistory = function (id) {
$scope.myHub.detailsSessoinMessage(id, $scope.agent.id);
};
$scope.agentMsgToUser = function (msg) {
var chatId = $scope.agentChatWithUser;
var customerName = $scope.customerName;
if (!customerName) {
angular.forEach($scope.customerVisit, function (index) {
if (index.connectionId == chatId) {
customerName = index.userName;
}
});
}
if (chatId !== "" && msg !== "") {
$scope.myHub.agentSendMessage(chatId, msg, customerName);
}
//not bind to scope.msg! not correctly work
$scope.msg = "";
$("#post-msg").val("");
};
$scope.closeChat = function (chatId) {
var item = $scope.chatConversation[getid(chatId)];
$scope.myHub.closeChat(chatId);
};
$scope.engageVisitor = function (newAgentId) {
var customerId = $scope.customerId;
var customerName = $scope.customerName;
var clientSessionId = $scope.clientSessionId;
$scope.myHub.engageVisitor(newAgentId, customerId, customerName, clientSessionId);
$("[data-dismiss=modal]").trigger({ type: "click" });
};
$scope.selectVisitor = function (customerId, customerName, clientSessionId) {
$scope.customerId = customerId;
$scope.customerName = customerName;
$scope.clientSessionId = clientSessionId;
$scope.myHub.showAgentList();
};
$scope.setClass = function (item) {
if (item === "من")
return "question";
else
return "response";
};
$scope.setdirectionClass = function (item) {
if (item === $scope.agent.name)
return { "float": "left" };
else
return { "float": "right" };
};
$scope.setArrowClass = function (item) {
if (item === $scope.agent.name)
return "left-arrow";
else
return "right-arrow";
};
$scope.setAlarm = function () {
$scope.alarmStatus = !$scope.alarmStatus;
};
}
}]);
app.directive("showtab", function () {
return {
link: function (scope, element, attrs) {
element.click(function (e) {
e.preventDefault();
$(element).addClass("active");
$(element).tab("show");
});
}
};
});
//زمان ارسال پیام
app.directive("timeAgo", function ($q) {
return {
restrict: "AE",
scope: false,
link: function (scope, element, attrs) {
jQuery.timeago.settings.strings =
{
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "پیش",
suffixFromNow: "از حالا",
seconds: "کمتر از یک دقیقه",
minute: "در حدود یک دقیقه",
minutes: "%d دقیقه",
hour: "حدود یگ ساعت",
hours: "حدود %d ساعت ",
day: "یک روز",
days: "%d روز",
month: "حدود یک ماه",
months: "%d ماه",
year: "حدود یک سال",
years: "%d سال",
wordSeparator: " ",
numbers: []
}
var parsedDate = $q.defer();
parsedDate.promise.then(function () {
jQuery(element).timeago();
});
attrs.$observe("title", function (newValue) {
parsedDate.resolve(newValue);
});
}
};
}); [HubName("chatHub")]
public class ChatHub : Microsoft.AspNet.SignalR.Hub
{
private readonly ApplicationDbContext _db = new ApplicationDbContext();
private static ConcurrentDictionary<string, UserInformation> _agents;
private static List<ChatSessionVm> _chatSessions;
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
public void Init()
{
_chatSessions = _chatSessions ?? (_chatSessions = new List<ChatSessionVm>());
_agents = _agents ?? (_agents = new ConcurrentDictionary<string, UserInformation>());
Clients.Caller.onlineStatus(_agents.Count(x => x.Value.IsOnline) > 0);
}
public void AgentConnect(string userName)
{
//ما برای ساده کردن مقایسه ساده ای انجام دادیم فقط کاربر حسین یا علی میتواند کارشناس باشد
if (userName == "hossein" || userName == "ali")
{
var agent = new UserInformation();
if (_agents.Any(item => item.Key == userName))
{
agent = _agents[userName];
agent.ConnectionId = Context.ConnectionId;
}
else
{
agent.ConnectionId = Context.ConnectionId;
agent.UserName = userName;
agent.IsOnline = true;
_agents.TryAdd(userName, agent);
}
Clients.Caller.loginResult(true, agent.ConnectionId, agent.UserName);
Clients.All.onlineStatus(_agents.Count(x => x.Value.IsOnline) > 0);
}
else
{
Clients.Caller.loginResult(false, null, null);
}
}
public void AgentChangeStatus(bool status)
{
var agent = _agents.FirstOrDefault(x => x.Value.ConnectionId == Context.ConnectionId).Value;
if (agent == null) return;
agent.IsOnline = status;
Clients.All.onlineStatus(_agents.Count(x => x.Value.IsOnline) > 0);
}
public void LogVisit(string city, string country, string firstComment, string userName)
{
foreach (var agent in _agents)
{
Clients.Client(agent.Value.ConnectionId).newVisit(userName, city, country, null, Context.ConnectionId, firstComment);
}
}
public void AcceptRequestChat(string customerConnectionId, string body, string userName)
{
var agent = FindAgent(Context.ConnectionId);
var session = _chatSessions.FirstOrDefault(item => item.Key.Equals(agent.Key));
if (session == null)
{
_chatSessions.Add(new ChatSessionVm
{
Key = agent.Key,
Value = new List<string> { customerConnectionId }
});
}
else
{
session.Value.Add(customerConnectionId);
}
Clients.Client(Context.ConnectionId).agentChat(customerConnectionId, body, userName);
Clients.Client(customerConnectionId).clientChat(customerConnectionId, agent.Value.UserName);
foreach (var item in _agents.Where(item => item.Value.IsOnline))
{
Clients.Client(item.Value.ConnectionId).refreshChatWith(agent.Value.UserName, customerConnectionId);
}
_db.Sessions.Add(new Session
{
AgentName = agent.Key,
CustomerName = userName,
CreatedDateTime = DateTime.Now
});
_db.SaveChanges();
var message = new Message
{
CreationTime = DateTime.Now,
Sender = agent.Key,
Receiver = userName,
Body = body,
//ConnectionId = _agents.FirstOrDefault(item => item.Value.UserName == userName).Key,
Session = _db.Sessions.OrderByDescending(item => item.Id)
.FirstOrDefault(item => item.AgentName.Equals(agent.Key) && item.CustomerName.Equals(userName))
};
_db.Messages.Add(message);
_db.SaveChanges();
}
public void GetAgentHistoryChat(string userName)
{
var dic = new Dictionary<int, int>();
var lenght = 0;
var chats = _db.Sessions.OrderBy(item => item.Id).Include(item => item.Parent)
.Where(item => item.AgentName.Equals(userName)).ToList();
foreach (var session in chats)
{
Result(session, ref lenght);
dic.Add(session.Id, lenght);
lenght = 0;
}
if (!chats.Any()) return;
var historyResult = chats.Select(item => new AgentViewModel
{
Id = item.Id,
CustomerName = item.CustomerName,
Date = item.CreatedDateTime,
Lenght = dic.Any(di => di.Key.Equals(item.Id)) ? dic.FirstOrDefault(di => di.Key.Equals(item.Id)).Value : 0,
}).OrderByDescending(item => item.Id).ToList();
Clients.Caller.receiveHistory(JsonConvert.SerializeObject(historyResult, new Formatting(), _settings));
}
public void DetailsSessoinMessage(int sessionId, string agentId)
{
var session = _db.Sessions.FirstOrDefault(item => item.Id.Equals(sessionId));
if (session == null) return;
var list = new List<Message>();
GetAllMessages(session, list);
var result = JsonConvert.SerializeObject(list.OrderBy(item => item.Id), new Formatting(), _settings);
Clients.Client(Context.ConnectionId).detailsHistory(result);
}
public void ClientSendMessage(string body, string userName)
{
var session = _chatSessions.FirstOrDefault(item => item.Value.Contains(Context.ConnectionId));
if (session == null || session.Key == null) return;
var agentId = _agents.FirstOrDefault(item => item.Key.Equals(session.Key)).Value.ConnectionId;
Clients.Caller.clientAddMessage("من", body);
Clients.Client(agentId).addMessage(Context.ConnectionId, userName, body);
var message = new Message
{
Sender = FindAgent(agentId).Key,
Receiver = userName,
Body = body,
CreationTime = DateTime.Now,
Session = FindSession(userName, FindAgent(agentId).Key)
};
_db.Messages.Add(message);
_db.SaveChanges();
}
public void AgentSendMessage(string id, string body, string userName)
{
var agent = FindAgent(Context.ConnectionId);
Clients.Caller.addMessage(id, agent.Value.UserName, body);
Clients.Client(id).clientAddMessage(agent.Value.UserName, body);
var message = new Message
{
Sender = agent.Key,
Receiver = userName,
Body = body,
Session = FindSession(agent.Key, userName),
CreationTime = DateTime.Now
};
_db.Messages.Add(message);
_db.SaveChanges();
}
public void CloseChat(string id)
{
var findAgent = FindAgent(Context.ConnectionId);
var session = _chatSessions.FirstOrDefault(item => item.Value.Contains(id));
if (session == null) return;
Clients.Client(id).clientAddMessage(findAgent.Key, "مکالمه شما با کارشناس مربوطه به اتمام رسیده است");
foreach (var agent in _agents)
{
Clients.Client(agent.Value.ConnectionId).refreshLeaveChat(agent.Value.UserName, id);
}
_chatSessions.Remove(session);
}
public void RequestChat(string message)
{
Clients.Caller.clientAddMessage("من", message);
}
public void EngageVisitor(string newAgentId, string cumtomerId, string customerName,string clientSessionId)
{
#region remove session of current agent
var currentAgent = FindAgent(Context.ConnectionId);
var currentSession = _chatSessions.FirstOrDefault(item => item.Value.Contains(cumtomerId));
if (currentSession != null)
{
_chatSessions.Remove(currentSession);
}
#endregion
#region add session to new agent
var newAgent = FindAgent(newAgentId);
var newSession = _chatSessions.FirstOrDefault(item => item.Key.Equals(newAgent.Key));
if (newSession == null)
{
_chatSessions.Add(new ChatSessionVm
{
Key = newAgent.Key,
Value = new List<string> { cumtomerId }
});
}
else
{
newSession.Value.Add(cumtomerId);
}
#endregion
Clients.Client(currentAgent.Value.ConnectionId).addMessage(cumtomerId, newAgent.Key,
"ادامه مکالمه به کارشناس " + newAgent.Key + "مقابل منتقل شد");
Clients.Client(newAgentId).addMessage(cumtomerId, currentAgent.Key,
"لطفا مکالمه را ادامه دهید.با تشکر");
Clients.Client(cumtomerId).clientAddMessage(newAgent.Value.UserName,
"مکالمه شما با کارشناس زیر برقرار گردید" + newAgent.Key);
var session = _db.Sessions.FirstOrDefault
(item => item.AgentName.Equals(currentAgent.Value.UserName)
&& item.CustomerName.Equals(customerName));
if (session != null)
{
var sessionId = session.Id;
var messages = _db.Messages.Where(item => item.Session.Id.Equals(sessionId));
var result = JsonConvert.SerializeObject(messages, new Formatting(), _settings);
Clients.Client(newAgentId).visitorSwitchConversation
(Context.ConnectionId, customerName, result, clientSessionId);
}
foreach (var item in _agents.Where(item => item.Value.IsOnline))
{
Clients.Client(item.Value.ConnectionId).refreshChatWith(newAgent.Value.UserName, cumtomerId);
}
_db.Sessions.Add(new Session
{
AgentName = newAgent.Key,
CustomerName = customerName,
CreatedDateTime = DateTime.Now,
Parent = _db.Sessions.Where(item => item.AgentName.Equals(currentAgent.Key)
&& item.CustomerName.Equals(customerName)).OrderByDescending(item => item.Id).FirstOrDefault()
});
_db.SaveChanges();
}
public void ShowAgentList()
{
Clients.Caller.agentList(_agents.ToList());
}
public override Task OnDisconnected(bool stopCalled)
{
var id = Context.ConnectionId;
var isAgent = _agents != null && _agents.Any(item => item.Value.ConnectionId.Equals(id));
if (isAgent)
{
UserInformation agent;
var currentAgentConnectionId = FindAgent(id).Key;
if (currentAgentConnectionId == null)
return base.OnDisconnected(stopCalled);
if (_chatSessions.Any())
{
var sessions = _chatSessions.FirstOrDefault(item => item.Key.Equals(currentAgentConnectionId));
//اطلاع دادن به تمام کاربرانی که در حال مکالمه با کارشناس هستند
if (sessions != null)
{
var result = sessions.Value.ToList();
for (var i = 0; i < result.Count(); i++)
{
var localId = result[i];
Clients.Client(localId).clientAddMessage(currentAgentConnectionId, "ارتباط شما با مشاور مورد نظر قطع شده است");
}
}
}
_agents.TryRemove(currentAgentConnectionId, out agent);
Clients.All.onlineStatus(_agents.Count(x => x.Value.IsOnline) > 0);
Clients.Client(id).loginResult(false, null, null);
}
else
{
if (_chatSessions == null ||
!_chatSessions.Any(item => item.Value.Contains(id)
&& _agents == null))
return base.OnDisconnected(stopCalled);
var session = _chatSessions.FirstOrDefault(item => item.Value.Contains(id));
if (session == null)
return base.OnDisconnected(stopCalled);
var agentName = session.Key;
var agent = _agents.FirstOrDefault(item => item.Key.Equals(agentName));
if (agent.Key != null)
{
Clients.Client(agent.Value.ConnectionId).addMessage(id, "کاربر", "اتصال با کاربر قطع شده است");
}
}
return base.OnDisconnected(stopCalled);
}
private KeyValuePair<string, UserInformation> FindAgent(string connectionId)
{
return _agents.FirstOrDefault(item => item.Value.ConnectionId.Equals(connectionId));
}
private Session FindSession(string key, string userName)
{
return _db.Sessions.Where(item => item.AgentName.Equals(key) && item.CustomerName.Equals(userName))
.OrderByDescending(item => item.Id).FirstOrDefault();
}
private static void Result(Session parent, ref int lenght)
{
while (true)
{
if (parent == null)
return;
lenght += parent.Messages.Count();
parent = parent.Parent;
}
}
private static List<Message> GetAllMessages(Session node, List<Message> list)
{
if (node == null) return null;
list.AddRange(node.Messages);
if (node.Parent != null)
{
GetAllMessages(node.Parent, list);
}
return null;
}
} <div>
<div>
<h2>
خوش آمدید
<span ng-bind="agent.name">
</span>
<a ng-click="changeAgentStatus()">
<i ng-if="changeStatus==null"
data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.lock"></i>
<i ng-if="changeStatus==true"
data-placement="bottom"
data-trigger="hover"
bs-tooltip="options.unlock"></i>
</a>
</h2>
<div style="float: left">
<a ng-click="setAlarm()">
<i ng-show="alarmStatus"
data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.alarmOn"></i>
<i ng-show="!alarmStatus"
data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.alarmOff"></i>
</a>
<!--<a data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.conversion" ng-click="showHistory()"><i></i></a>-->
<a data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.edit"><i></i><span></span></a>
<a data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.setting"><i></i></a>
<a data-placement="bottom"
data-trigger="hover "
bs-tooltip="options.signOut" ng-click="LeaveChat()"><i></i><span></span></a>
</div>
</div>
<div>
<div>
<div id="chat-content">
<div>
<ul>
<li>
<a showtab href="#online-list">آنلاین</a>
</li>
<li>
<a ng-click="showHistory()" showtab href="#conversation">آرشیو گفتگوها</a>
</li>
</ul>
<div>
<div id="online-list">
<div>
<h2>
<i></i><span></span>
<span>نمایش آنلاین مراجعه ها</span>
</h2>
</div>
<div>
<div id="agent-chat">
<div id="real-time-visits">
<table id="current-visits">
<thead>
<tr>
<th>نام کاربر</th>
<th>زمان اولین تقاضا</th>
<th>منطقه</th>
<th>پاسخ</th>
</tr>
</thead>
<tbody>
<tr id="{{item.connectionId}}" ng-animate="animate" ng-repeat="item in customerVisit ">
<td ng-bind="item.userName"></td>
<td>
<span time-ago title="{{item.date}}"></span>
</td>
<td>
<span ng-bind="item.country"></span> /<span ng-bind="item.city"> </span>
</td>
<td>
<a style="cursor: pointer" ng-if="item.chatWith== null"
ng-click="acceptRequestChat(item.connectionId,item.firstComment,item.userName)">
شروع مکالمه
</a>
<span ng-if="item.chatWith ">
وضعیت:
<span>در حال مکالمه با</span>
<span ng-bind="item.chatWith"></span>
<a ng-show="item.chatWith==agent.name"
ng-click="selectVisitor(item.connectionId,item.userName,item.connectionId)">
انتقال مکالمه
</a>
</span>
<ul ng-repeat="session in chatSessions track by $index" style="padding:0px;">
<li ng-if="session.id==item.connectionId" id="{{session.id}}">
<div>
<p>
تاریخ شروع مکالمه:
<span time-ago title="{{session.date}}"></span>
</p>
<p>
تعداد پیام ها:
<span ng-bind="session.length"></span>
</p>
</div>
<p>
<a ng-click="detailsChat(session.id,session.userName)">جزییات </a>
<a ng-click="closeChat(session.id)">
خاتمه عملیات
</a>
</p>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="conversation">
<div>
<h2>
<i></i><span></span>
<span>آرشیو گفتگوهای </span>
{{agent.name}}
</h2>
</div>
<div>
<div>
<table id="current-visits">
<thead>
<tr>
<th>شناسه مشتری</th>
<th>نام مشتری</th>
<th>تعداد محاوره ها</th>
<th>تاریخ</th>
<th>جزئیات</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in agentHistory track by $index">
<td ng-bind="item.id"></td>
<td ng-bind="item.customerName"></td>
<th ng-bind="item.lenght"></th>
<td><span time-ago title="{{item.date}}"></span></td>
<th>
<ang-click="detailsChatHistory(item.id)" >مشاهده جزییات گفتگو</a>
</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="detailsAgentHistory" tabindex="-1" role="dialog" aria-labelledby="cmdLabel" aria-hidden="true">
<div>
<div>
<div>
<div>
<button type="button" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<h2>
<span></span>تاریخچه گفتگو
</h2>
</div>
<div>
<div style="display: block">
<ul ng-repeat="item in historyMsg">
<li>
<span ng-bind="item.name" ng-style="setdirectionClass(item.name)">
</span>
<span ng-style="setdirectionClass(item.name)">
<span ng-class="setArrowClass(item.name)"></span>
<span time-ago title="{{item.date}}"></span>
<span>
<p ng-bind-html="item.msg | smilies"></p>
</span>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="agentList" tabindex="-1" role="dialog" aria-labelledby="cmdLabel" aria-hidden="true">
<div>
<div>
<div>
<div>
<button type="button" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<h2>
<span></span>لیست تمام کارشناسان
</h2>
</div>
<div>
<div style="display: block;">
<div ng-show="agentList.length==0">
کارشناس آنلاینی وجود ندارد
</div>
<ul ng-repeat="item in agentList">
<li>
<span>
<a ng-click="engageVisitor(item.id)">{{item.name}}</a>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="agentUserChat" tabindex="-1" role="dialog" aria-labelledby="cmdLabel" aria-hidden="true">
<div>
<div>
<div>
<div>
<button type="button" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<h2>
<span></span>گفتگو
</h2>
</div>
<div>
<div>
<div>
<div style="display: block;">
<label>شروع چت در </label>:
<span ng-bind="dateStartChat"></span>
<ul>
<li ng-repeat="item in agentUserMsgs">
<span ng-bind="item.name" ng-style="setdirectionClass(item.name)">
</span>
<span ng-style="setdirectionClass(item.name)">
<span ng-class="setArrowClass(item.name)"></span>
<span time-ago title="{{item.date}}"></span>
<span>
<p ng-bind-html="item.msg | smilies"></p>
</span>
</span>
</li>
</ul>
<div>
<div>
<textarea id="post-msg" ng-model="msg" placeholder="متن خود را وارد نمایید" style="overflow: hidden; word-wrap: break-word; resize: horizontal; height: 80px; max-width: 100%"></textarea>
<span smilies-selector="msg" smilies-placement="right" smilies-title="Smilies"></span>
</div>
<div style="text-align: center; margin-top: 5px">
<button ng-click="agentMsgToUser(msg)">ارسال</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> <html ng-app="app">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Support</title>
<link href="~/Content/bootstrap-rtl.css" rel="stylesheet" />
<link href="~/Scripts/smilies/angular-smilies-embed.css" rel="stylesheet" />
<link href="~/Content/font-awesome.css" rel="stylesheet" />
<link href="~/Content/toastr.css" rel="stylesheet" />
<link href="~/Content/liveSupport.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/toastr.js"></script>
<script src="~/Scripts/jquery.timeago.js"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-animate.js"></script>
<script src="~/Scripts/angular-sanitize.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/angular-strap.js"></script>
<script src="~/Scripts/angular-strap.tpl.js"></script>
<script src="~/Scripts/smilies/angular-smilies.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
<script src="~/Scripts/angular-signalr-hub.js"></script>
<script src="~/app/app.js"></script>
@Scripts.Render("~/bundles/bootstrap")
</head>
<body ng-controller="ChatCtrl">
<div ng-view>
</div>
<div id="chat-box-header" ng-click="boxheader()">
{{chatTitle}}
</div>
<div id="chat-box">
<div ng-show="hasOnline">
<div id="style-1" style="min-height:100px;">
<div ng-repeat="item in clientAgentMsg track by $index">
<span ng-class="setClass(item.name)">
{{item.name}}
</span>
<br />
<p ng-bind-html="item.msg | smilies"></p>
</div>
</div>
<div>
<label>پیام</label>
<div style="text-align: left; clear: both">
<a data-placement="top"
data-trigger="hover "
bs-tooltip="options.alarm" ng-click="alarm()"><i></i></a>
<a data-placement="top"
data-trigger="hover "
bs-tooltip="options.signOut" href="signOut()"><i></i><span></span></a>
<a data-placement="top"
data-trigger="hover "
bs-tooltip="options.upload" href="fileupload()">
<span><i></i></span>
</a>
</div>
<div>
<textarea style="height: 150px; max-height: 160px;" ng-model="message" placeholder=" متن خود را وارد نمایید"></textarea>
<span smilies-selector="message" smilies-placement="right" smilies-title="Smilies"></span>
</div>
</div>
<div style="text-align: center">
<button type="button" ng-disabled="pendingRequestChat" ng-click="requestChat(message)">ارسال </button>
</div>
</div>
<div ng-show="hasOffline">
<div>
<form name="Ticket" id="form1">
<fieldset>
<div>
<label>نام</label>
<input name="email"
ng-model="ticket.name"
>
</div>
<div>
<label>ایمیل</label>
<input name="email"
ng-model="ticket.email"
>
</div>
<div>
<label>پیام</label>
</div>
<div>
<textarea ng-model="ticket.comment" placeholder="متن خود را وارد نمایید"></textarea>
<span smilies-selector="ticket.comment" smilies-placement="right" smilies-title="Smilies"></span>
</div>
</fieldset>
<div style="text-align: center">
<button type="button"
ng-click="ticket.submit(ticket)">
ارسال
</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html> app.MapSignalR();
Could not load file or assembly 'Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
PM> update-package Microsoft.AspNet.Mvc PM> update-package Microsoft.Web.Infrastructure PM> Update-package -reinstall PM> Update-package -safe