Javascript 信号器-如果集线器联机,则显示消息
我正在建立一个聊天室,客户可以在这里与支持团队聊天 所有客户端网站都有一个聊天室。支持团队有一个站点。当支持团队登录到该站点时。集线器连接可用,聊天室打开 但是在客户端网站上,当supportTeam启动hub时,我如何显示一条消息:类似于:Javascript 信号器-如果集线器联机,则显示消息,javascript,jquery,signalr,Javascript,Jquery,Signalr,我正在建立一个聊天室,客户可以在这里与支持团队聊天 所有客户端网站都有一个聊天室。支持团队有一个站点。当支持团队登录到该站点时。集线器连接可用,聊天室打开 但是在客户端网站上,当supportTeam启动hub时,我如何显示一条消息:类似于: alert('cht is now online'); 我的尝试: ChatHub.cs public void AdminJoin() { var adminUser = "Chat is now open"
alert('cht is now online');
我的尝试:
ChatHub.cs
public void AdminJoin()
{
var adminUser = "Chat is now open"
Clients.All.AdminIsOnline(adminUser);
}
客户网站上的代码:
chat.on('AdminIsOnline', function (adminUser) {
adminHasJoined(adminUser);
});
function adminHasJoined(adminUser) {
alert(adminUser);
};
以上代码仅在我刷新客户机网站页面以及SuppertTeam网站联机时运行。
我希望每次支持团队登录时都显示警报。不仅仅是页面刷新简而言之:
1.继承OnConnect方法。
2.将用户添加到组。
3.创建将通知组中所有成员有关新组成员的方法。
4.使用JS通知客户端的事件。
中心示例:
public class ChatHub : Hub
{
PREPP2Entities db = new PREPP2Entities();
//Send message to chat room
public void SendChatMessage(string gn, string name, string message)
{
Clients.Group(gn).addChatMessage(name, message);
UserStatus();
}
//Public method that available on client side and used to update user status on user actions (e.g.Connect, disconnect
public void UserStatus()
{
Clients.All.updateStatus();
}
public override Task OnConnected()
{
//get user data
var x = (from a in db.Users where a.Login.Contains(Context.User.Identity.Name) select a.Role).FirstOrDefault();
//Add to the list of online users
if (AlreadyOnline(Context.ConnectionId) == false)
{
try
{
UsersOnline uo = new UsersOnline();
uo.ConnectionID = Context.ConnectionId;
uo.UserName = Context.User.Identity.Name;
uo.UserRole = x;
uo.Created = DateTime.Now;
db.UsersOnline.Add(uo);
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(y => y.ValidationErrors)
.Select(y => y.ErrorMessage);
var fullErrorMessage = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
//User with role "User"
if (x == 1)
{
//Add user to group
JoinGroup(Context.ConnectionId, Context.User.Identity.Name, true);
var operatorName = GetOperator();
//Find connection id
var cid = (from a in db.UsersOnline where a.UserName.Contains(operatorName) & a.UserRole == 2 select a.ConnectionID).FirstOrDefault();
if (cid != null & !String.IsNullOrEmpty(cid))
{
//Add user to group
JoinGroup(cid, Context.User.Identity.Name, false);
}
else
{
//Message that nobody's here
StringBuilder sb = new StringBuilder(200);
sb.AppendFormat("Здравствуйте {0}! ", Context.User.Identity.Name);
sb.Append("К сожалению сейчас наших стилистов нет в сети.<br />");
sb.Append("Вы можете оставить сообщение, которое будет прочитано позже.");
string message = sb.ToString();
SendChatMessage(Context.User.Identity.Name, "PREPP", message);
}
}
//Else user role belong to support team
else
{
//Find users that has this support team to talk
var oid = (from a in db.Users where a.Login.Contains(Context.User.Identity.Name) select a.Id).FirstOrDefault();
var u = (from a in db.UsersOnline
join b in db.Users on a.UserName equals b.Login
where a.UserRole == 1 & b.OperatorID == oid
select a.UserName).ToArray();
foreach (string n in u)
{
JoinGroup(Context.ConnectionId, n, false);
}
}
}
UserStatus();
return base.OnConnected();
}
public void JoinGroup(string connectionid, string groupName, bool send)
{
try
{
GroupInfo gi = new GroupInfo();
gi.UserConnection = connectionid;
gi.GroupName = groupName;
gi.Created = DateTime.Now;
db.GroupInfo.Add(gi);
db.SaveChanges();
Groups.Add(connectionid, groupName);
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
var fullErrorMessage = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
if (send == true)
{
var on = GetOperator();
StringBuilder sb = new StringBuilder(200);
sb.AppendFormat("Здравствуйте {0}! ", Context.User.Identity.Name);
sb.AppendFormat("Я Ваш личный стилист - {0}. ", on);
sb.Append("Чем сегодня я могу помочь Вам?");
string message = sb.ToString();
SendChatMessage(groupName, on, message);
}
UserStatus();
}
public bool AlreadyOnline(string connectionid)
{
bool exist;
var x = db.UsersOnline.Where(p => p.ConnectionID.Contains(connectionid)).Count();
if (x > 0)
{
exist = true;
}
else
{
exist = false;
}
return exist;
}
public override Task OnDisconnected()
{
StringBuilder sb = new StringBuilder(100);
sb.AppendFormat("Пользователь {0} не в сети!", Context.User.Identity.Name);
string message = sb.ToString();
SendChatMessage(Context.User.Identity.Name, "PREPP", message);
UserStatus();
db.GroupInfo.RemoveRange(db.GroupInfo.Where(x => x.UserConnection.Contains(Context.ConnectionId)));
db.UsersOnline.RemoveRange(db.UsersOnline.Where(x => x.UserName.Contains(Context.User.Identity.Name)));
db.SaveChangesAsync();
UserStatus();
return base.OnDisconnected();
}
public override Task OnReconnected()
{
StringBuilder sb = new StringBuilder(100);
sb.AppendFormat("Пользователь {0} вернулся к нам!", Context.User.Identity.Name);
string message = sb.ToString();
SendChatMessage(Context.User.Identity.Name, "PREPP", message);
UserStatus();
return base.OnReconnected();
}
public string GetOperator()
{
//Возвращаем имя оператора если он был назначен ранее
var oid = (from a in db.Users where a.Login.Contains(Context.User.Identity.Name) select a.OperatorID).FirstOrDefault();
if (oid.HasValue)
{
return db.Users.Where(x => x.Id == oid).Select(x => x.Login).SingleOrDefault();
}
//Выбираем и добавляем пользователю случайного оператора
else
{
//выбираем всех пользователей с ролью оператора
var opname = (from a in db.UsersOnline where a.UserRole == 2 orderby (Guid.NewGuid()) select a.UserName).FirstOrDefault();
//Назначем пользователю оператора
var opid = (from a in db.Users where a.Login.Contains(opname) select a.Id).SingleOrDefault();
if (opid > 0)
{
WriteOperator(Context.User.Identity.Name, opid);
return opname;
}
else
{
var op = (from a in db.Users where a.Role == 2 orderby (Guid.NewGuid()) select a.Id).FirstOrDefault();
WriteOperator(Context.User.Identity.Name, op);
return db.Users.Where(x => x.Id == op).Select(x => x.Login).SingleOrDefault();
}
}
}
void WriteOperator(string username, int operatorid)
{
var uid = db.Users.Where(p => p.Login == username).Select(x => x.Id).FirstOrDefault();
var a = db.Users.Find(uid);
if (a != null)
{
a.OperatorID = operatorid;
db.SaveChanges();
}
else throw new Exception();
}
}谢谢你的回答。我在找更简单的东西。如果找不到连接,我是否可以添加一个自动尝试重新连接集线器到客户端网站?javascript看起来是什么样子?默认情况下,一旦与服务器的连接断开,SignalR客户端就会尝试重新连接。你想在这里实现什么?@Chris问题是我需要刷新客户端网站以连接到中心。这是一个场景:如果一个用户访问一个客户端网站,而中心处于脱机状态,那么我当然无法连接。当adn仍在客户端网站上时,启动supportSitehub。然后我想在客户网站上显示一条消息,说明hub在线。无需刷新页面@用户3228992这是不可行的。如果您的用户浏览到该页面,但中心已关闭,则强制客户端连接的唯一方法是刷新页面或使用按钮调用连接;有些事情是我们无法控制的。也许您可以在javascript中实现一个循环/计时器,在服务器脱机时尝试重新连接,但这将严重干扰正常的Signal工作流。这是一个可行的方法,但这不是我给你们的例子。当然,这需要一些客户端的魔法,就像我在Knockout.js上做的那样