Как отправить сообщение автономному пользователю в чат-программе SignalR?
Я использую SignalR для общения на своем веб-сайте, и мне нужно иметь возможность отправлять сообщения как онлайн-пользователям, так и тем, которые в данный момент находятся в автономном режиме. Я успешно встроил SignalR в свой проект, и все работает отлично, за исключением чата в автономном режиме. Я понятия не имею, почему это не сработает.
Поскольку я использую Umbraco CMS в фоновом режиме, я могу получить доступ к различным идентификаторам члена Umbraco простым способом. Поэтому у него всегда есть необходимые идентификаторы для создания группы, как идентификатор отправителя, так и идентификатор получателя. Итак, почему автономный чат все еще не работает? Почему окно чата не открывается, когда пользователь не в сети?
Я приложил свой View и мой Hub, и я надеюсь, что кто-нибудь может мне помочь.
Мой ChatHub
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR.Hubs;
using Microsoft.AspNet.SignalR.Transports;
using Microsoft.AspNet.SignalR.Infrastructure;
using Microsoft.AspNet.SignalR;
using System.Threading.Tasks;
using System.Timers;
using Umbraco714.Modal;
using Umbraco.Core;
using Umbraco714.Repositories;
using Umbraco714.Models;
using System.Diagnostics;
using System.Collections;
namespace Umbraco714.Hubs
{
[HubName("chatHub")]
public class ChatHub : Hub
{
public Task JoinGroup()
{
return Groups.Add(Context.ConnectionId, "foo");
}
/*
Method to send a message or a message history to both chat partners in a specific group
*/
public void Send(string message, string groupName)
{
var chatrepo = new ChatRepository();
if (Clients != null)
{
// Call the addMessage method on all clients
Clients.Group(groupName).addMessage(message, groupName, chatrepo.GetAll(groupName));
if (chatrepo.GetAll(groupName).Count < 3)
{
var repo = new ChatRepository();
repo.Insert(new ChatMessage(message, groupName, DateTime.Now));
}
}
}
/*
Method which notify all existing online users about new user coming online by updating the online users list
*/
public override Task OnConnected()
{
var newUsers = OnlineUser.userObj.Where(item => item.newStatus == true).Select(item => item.userId).ToList();
UserModal user = OnlineUser.userObj.Where(item => item.sessionId == HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value.ToString()).SingleOrDefault();
user.connectionId = Context.ConnectionId;
return Clients.All.joined(Context.ConnectionId, newUsers);
}
/*
Method to pass the list of the online users to the newly connected user
*/
public void GetAllOnlineStatus()
{
Clients.Caller.OnlineStatus(Context.ConnectionId, OnlineUser.userObj.Select(item => item.userId).ToList());
}
/*
Method to create a group of any given pair of users
*/
public string CreateGroup(string currentUserId, string toConnectTo)
{
string strGroupName = GetUniqueGroupName(currentUserId, toConnectTo);
string connectionId_To = OnlineUser.userObj.Where(item => item.userId == toConnectTo).Select(item => item.connectionId).SingleOrDefault();
if (!string.IsNullOrEmpty(connectionId_To))
{
var chatrepo = new ChatRepository();
//create the new group with the two member id's
Groups.Add(Context.ConnectionId, strGroupName);
Groups.Add(connectionId_To, strGroupName);
Clients.Caller.setChatWindow(strGroupName, toConnectTo, chatrepo.GetAll(strGroupName));
return strGroupName;
}
return null;
}
/*
Method to create a unique group name
*/
private string GetUniqueGroupName(string currentUserId, string toConnectTo)
{
return (currentUserId.GetHashCode() ^ toConnectTo.GetHashCode()).ToString();
}
}
}
Мой чат Просмотр
@using System;
@using System.Collections.Generic;
@using System.Linq;
@using System.Web;
@using Umbraco714.Models;
@using Umbraco714.Repositories;
@using Umbraco.Core;
@using Umbraco.Core.Persistence;
@using Umbraco.Core.Services;
@using Umbraco.Web.Security;
@using Umbraco.Web;
@using Umbraco.Web.Models;
@using Umbraco.Core.Models;
@using System.Web.Security;
@{
var memberShipHelper = new Umbraco.Web.Security.MembershipHelper(Umbraco.Web.UmbracoContext.Current);
var memberId = memberShipHelper.GetCurrentMemberId();
var member = ApplicationContext.Current.Services.MemberService.GetById(memberId);
}
<div class="container">
<form id="chatForm">
<div id="divChatWindow" style="border: 1px solid #3366CC; float: left; width: 365px; display: none; margin-right: 10px">
<div id="messageBox" style="border: 1px solid blue;">
<ul id="messages" style="width: 365px; height: 100px; font: normal 2 verdana; font-size:12px; overflow: auto; margin-bottom: 0px; word-wrap: break-word;"></ul>
</div>
<hr />
<input type="text" id="msg" class="ChatText" style="width: 280px; height:22px; border-color: #666699; border-style: solid; border-width: 1px; " />
<input type="button" id="btnChatSend" class="ChatSend" value="Send" style="background-color: #99ccff; font-size: smaller; border: 1px solid #0066FF; height:24px" />
</div>
<br />
<label id="lblUserName" style="font-weight:bold" />
<br />
<div id="userList" style="border: thin solid #C0C0C0; font-family: Tunga; width: 150px; font-weight: 500;">
@foreach (var user in ApplicationContext.Current.Services.MemberService.GetAllMembers().OrderBy(n => n.Name))
{
if (@user.Properties["nickname"].Value != null)
{
if (@user.Id != @member.Id)
{
<img src="~/img/offline.png" data-userid="@user.Id" class="UserImg" width="18" height="18" />
<a class="UserItem" data-userid="@user.Id" href="#">@user.Properties["nickname"].Value.ToString()</a>
<br />
}
}
}
</div>
<div style="float: left" id="chatContainer">
</div>
</form>
<input type="hidden" id="hdnUserId" value="@ViewData["hdnUserId"]" />
<input type="hidden" id="hdnUserName" value="@ViewData["hdnUserName"]" />
<div class="modal fade" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<
</div>
<div class="modal-footer">
<input type="hidden" id="ConnectTo" value="0" name="ConnectTo" />
<button class="btn btn-default" data-dismiss="modal"></button>
<button id="SendRequest" value="SendRequest" name="ButtonId" class="btn btn-primary"></button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
$(document).ready(function () {
// Proxy created on the fly
var chat = $.connection.chatHub;
//Get called from the GetAllOnlineStatus methode in the Chat Hub to pass the online user list to the newly connected user
chat.client.OnlineStatus = function (connectionId, userList) {
$("img[id^=stat]").attr('src', 'img/offline.png');
$(userList).each(function (index, obj) {
$("div#userList a[data-userid='" + obj + "']").addClass('online');
$("div#userList img[data-userid='" + obj + "']").attr('src', 'img/online.png');
});
};
//Get called from the OnConnected methode in the Chat Hub to update the online user List for existing users
chat.client.joined = function (connectionId, userList) {
$(userList).each(function (index, obj) {
$("div#userList a[data-userid='" + obj + "']").addClass('online');
$("div#userList img[data-userid='" + obj + "']").attr('src', 'img/online.png');
});
};
// make the chat window visible
chat.client.setChatWindow = function (strGroupName, strChatTo, listMessages) {
if ($('div[groupname=' + strGroupName + ']').length == 0) {
$('div[chatToId=' + strChatTo + ']').attr('groupname', strGroupName);
$('div[chatToId=' + strChatTo + ']').css('display', 'block')
//load history from SendClient
for (var i = 0, l = listMessages.length; i < l; i++) {
$('div[groupname=' + strGroupName + ']').find('ul').append('<li>' + listMessages[i].message + '</li>').scrollTop($('html, body').height());
}
}
};
// Declare a function on the chat hub so the server can invoke it
chat.client.addMessage = function (message, groupName, listMessages) {
if ($('div[groupname=' + groupName + ']').length == 0) {
// Load history from the SendClient
for (var i = 0, l = listMessages.length; i < l; i++) {
$('#divChatWindow').find('#messages').append('<li>' + listMessages[i].message + '</li>');
}
var chatWindow = $("#divChatWindow").clone(true);
$(chatWindow).css('display', 'block');
$(chatWindow).attr('groupname', groupName);
$("#chatContainer").append(chatWindow);
}
if (listMessages.length < 3) {
$('div[groupname=' + groupName + ']').find('ul').append('<li>' + message + '</li>').scrollTop($('html, body').height());
} else {
var toId = $('div[groupname=' + groupName + ']').attr('chattoid')
console.log(toId)
$('#myModal').find('#ConnectTo').val(toId)
$('#myModal').modal()
}
};
$("#broadcast").click(function () {
// Call the chat method on the server
chat.server.send($('#msg').val());
});
// Start the connection
$.connection.hub.start(function () {
chat.server.getAllOnlineStatus();
});
$('.UserItem').click(function () {
// Pass the Id from the current logged in Member and his chat partner to the Hub method CreateGroup
chat.server.createGroup($('#hdnUserId').val(), $(this).attr('data-userid'));
var chatWindow = $("#divChatWindow").clone(true);
$(chatWindow).attr('chatToId', $(this).attr('data-userid'));
$("#chatContainer").append(chatWindow);
return false;
});
// submit button click event
$(".ChatSend").click(function () {
strChatText = $('.ChatText', $(this).parent()).val();
if (strChatText != '') {
var strGroupName = $(this).parent().attr('groupname');
if (typeof strGroupName !== 'undefined' && strGroupName !== false)
chat.server.send($("#hdnUserName").val() + ' : ' + strChatText, $(this).parent().attr('groupname'));
$('.ChatText', $(this).parent()).find('ul').append(strChatText);
$('.ChatText', $(this).parent()).val('');
}
return false;
});
$(".ChatText").keypress(function (e) {
if (e.keyCode == 13) {
strChatText = $('.ChatText', $(this).parent()).val();
if (strChatText != '') {
var strGroupName = $(this).parent().attr('groupname');
if (typeof strGroupName !== 'undefined' && strGroupName !== false)
chat.server.send($("#hdnUserName").val() + ' : ' + strChatText, $(this).parent().attr('groupname'));
$('.ChatText', $(this).parent()).find('ul').append(strChatText);
$('.ChatText', $(this).parent()).val('');
}
}
});
});
</script>
1 ответ
Вам необходимо отслеживать состояние пользователя (эта способность не встроена в signalR) и отправлять данные только тем пользователям, которые находятся в сети.
Узнайте, как отслеживать онлайн-пользователей, https://www.simple-talk.com/dotnet/asp.net/tracking-online-users-with-signalr/