我开发了一个私人聊天中心,用户可以登录并查看其他用户的列表。每个用户的名字旁边都有一个聊天按钮。
当用户单击聊天按钮时,他们会被重定向到聊天页面,可以在其中开始发送消息。但是,当前存在一个问题,即消息仅向发送者显示,接收者必须重新加载页面才能查看数据库中的消息。
我正在寻找一种解决方案,使消息也能实时显示给接收者。
聊天室
using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using DashBoard1.Models;
namespace DashBoard1.Hubs
{
public class ChatHub : Hub
{
private ApplicationDbContext db = new ApplicationDbContext();
public async Task SendMessage(string sender, string receiver, string message)
{
var user = db.Users.FirstOrDefault(u => u.Email.ToLower() == receiver.ToLower());
if (user != null)
{
var userId = user.Id;
var chatMessage = new ChatViewModel()
{
SenderEmail = sender,
ReceiverEmail = receiver,
Message = message,
SentAt = DateTime.Now
};
db.Chat.Add(chatMessage);
db.SaveChanges();
await Clients.Caller.sendMessage(sender, message);
await Clients.User(userId).sendMessage(sender, message);
await Clients.User(userId).updateChat();
}
}
}
}
聊天视图
@{
ViewBag.Title = "Chat";
}
<h2>Chat</h2>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendMessage" value="Send" />
<input type="hidden" id="senderEmail" value="@ViewBag.currentUser" />
<input type="hidden" id="receiverEmail" value="@ViewBag.receiverEmail" />
<ul id="messageList">
@{foreach (var message in Model)
{
<li><strong>@message.SenderEmail</strong>: @message.Message</li>
}
}
</ul>
</div>
@section scripts {
<!--Script references. -->
<!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
<!--Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.4.3.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!--SignalR script to update the chat page and send messages.-->
<script>
$(function () {
// Reference the auto-generated proxy for the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call back to display messages.
chat.client.sendMessage = function (sender, message) {
// Add the message to the page
$('#messageList').append('<li><strong>' + htmlEncode(sender) + '</strong>: ' + htmlEncode(message) + '</li>');
$('#messageList').scrollTop($('#messageList')[0].scrollHeight);
};
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendMessage').click(function () {
// Call the Send method on the hub.
chat.server.sendMessage($('#senderEmail').val(), $('#receiverEmail').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
chat.client.updateChat = function () {
// Reload the page to retrieve the updated messages from the database
location.reload();
};
});
});
// This optional function html-encodes messages for display in the page.
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
}
聊天操作方法
[Authorize(Roles = "Accountant")]
public ActionResult Chat(string receiverEmail)
{
var currentUser = UserManager.FindById(User.Identity.GetUserId()).Email;
ViewBag.currentUser = currentUser;
ViewBag.receiverEmail = receiverEmail;
var messages = _context.Chat.Where(m => (m.SenderEmail == currentUser && m.ReceiverEmail == receiverEmail) || (m.SenderEmail == receiverEmail && m.ReceiverEmail == currentUser)).ToList();
return View(messages);
}
用户列表
@if (Model != null)
{
foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
@Html.ActionLink("Chat", "Chat", "Home", new { receiverEmail = item.Email }, new { @class = "chat-button" })
</td>
</tr>
}
}
会计行动方法
//public ActionResult AccountantIndex(int clientid)
[Authorize(Roles = "Accountant")]
public ActionResult Accountants()
{
var currentUser = UserManager.FindById(User.Identity.GetUserId());
ViewBag.currentUser = currentUser;
var accountants = _context.Users.Where(u => u.Id != currentUser.Id && u.Roles.Any(r => r.RoleId == "ba28c9e7-414b-489b-99e7-d97fd4ade08b")).ToList();
return View(accountants);
}
我这样做的方法是当消息发送后,获取信号 r 向其他人广播消息,然后在收到消息时刷新消息。我知道你使用 js,但这是一个 C# 版本:
发送时:
await Clients.Client("").SendAsync("newMessageSent");
收到消息更新:
hubConnection.On("newMessageSent", async () => { //update chat });
如果你愿意的话,你可以使用它作为基础并在 js 中进行