gpt4 book ai didi

asp.net-mvc - 使用 chatjs.net SignalR MVC 聊天的好友列表

转载 作者:行者123 更新时间:2023-12-04 21:18:07 26 4
gpt4 key购买 nike

我开始使用 chatjs.net 实现一个网络聊天系统.但我想知道 friend 列表应该绑定(bind)聊天列表。我指的是与 ROOM_ID_STUB 的房间聊天记录了用户名。但在我的情况下, friend 列表将显示在线和离线用户,不像所有示例 chatjs.net 只会是单人间。

任何人都可以建议我绑定(bind)我的 friend 列表的正确方法,并且每个登录的用户都会有一个聊天室,他们一起共享房间聊天列表?

public class ChatHub : Hub, IChatHub
{
/// <summary>
/// This STUB. In a normal situation, there would be multiple rooms and the user room would have to be
/// determined by the user profile
/// </summary>
public const string ROOM_ID_STUB = "chatjs-room";

/// <summary>
/// Current connections
/// 1 room has many users that have many connections (2 open browsers from the same user represents 2 connections)
/// </summary>
private static readonly Dictionary<string, Dictionary<int, List<string>>> connections = new Dictionary<string, Dictionary<int, List<string>>>();

/// <summary>
/// This is STUB. This will SIMULATE a database of chat messages
/// </summary>
private static readonly List<DbChatMessageStub> dbChatMessagesStub = new List<DbChatMessageStub>();

/// <summary>
/// This method is STUB. This will SIMULATE a database of users
/// </summary>
private static readonly List<DbUserStub> dbUsersStub = new List<DbUserStub>();

/// <summary>
/// This method is STUB. In a normal situation, the user info would come from the database so this method wouldn't be necessary.
/// It's only necessary because this class is simulating the database
/// </summary>
/// <param name="newUser"></param>
public static void RegisterNewUser(DbUserStub newUser)
{
if (newUser == null) throw new ArgumentNullException("newUser");
dbUsersStub.Add(newUser);
}

/// <summary>
/// This method is STUB. Returns if a user is registered in the FAKE DB.
/// Normally this wouldn't be necessary.
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public static bool IsUserRegisteredInDbUsersStub(DbUserStub user)
{
return dbUsersStub.Any(u => u.Id == user.Id);
}

/// <summary>
/// Tries to find a user with the provided e-mail
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
public static DbUserStub FindUserByEmail(string email)
{
if (email == null) return null;
return dbUsersStub.FirstOrDefault(u => u.Email == email);
}

/// <summary>
/// If the specified user is connected, return information about the user
/// </summary>
public ChatUser GetUserInfo(int userId)
{
var user = dbUsersStub.FirstOrDefault(u => u.Id == userId);
return user == null ? null : GetChatUserFromDbUserId(userId);
}

private ChatUser GetChatUserFromDbUserId(int dbUserId)
{
var myRoomId = this.GetMyRoomId();

// this is STUB. Normally you would go to the database get the real user
var dbUser = dbUsersStub.First(u => u.Id == dbUserId);

ChatUser.StatusType userStatus;
lock (connections)
{
userStatus = connections.ContainsKey(myRoomId)
? (connections[myRoomId].ContainsKey(dbUser.Id)
? ChatUser.StatusType.Online
: ChatUser.StatusType.Offline)
: ChatUser.StatusType.Offline;
}
return new ChatUser()
{
Id = dbUser.Id,
Name = dbUser.FullName,
Status = userStatus,
ProfilePictureUrl = GravatarHelper.GetGravatarUrl(GravatarHelper.GetGravatarHash(dbUser.Email), GravatarHelper.Size.s32)
};
}

private ChatMessage GetChatMessage(DbChatMessageStub chatMessage, string clientGuid)
{
return new ChatMessage()
{
Message = chatMessage.Message,
UserFrom = this.GetChatUserFromDbUserId(chatMessage.UserFromId),
UserTo = this.GetChatUserFromDbUserId(chatMessage.UserToId),
ClientGuid = clientGuid
};
}

/// <summary>
/// Returns my user id
/// </summary>
/// <returns></returns>
private int GetMyUserId()
{
// This would normally be done like this:
//var userPrincipal = this.Context.User as AuthenticatedPrincipal;
//if (userPrincipal == null)
// throw new NotAuthorizedException();

//var userData = userPrincipal.Profile;
//return userData.Id;

// But for this example, it will get my user from the cookie
return ChatCookieHelperStub.GetDbUserFromCookie(this.Context.Request).Id;
}

private string GetMyRoomId()
{
// This would normally be done like this:
//var userPrincipal = this.Context.User as AuthenticatedPrincipal;
//if (userPrincipal == null)
// throw new NotAuthorizedException();

//var userData = userPrincipal.Profile;
//return userData.MyTenancyIdentifier;

// But for this example, it will always return "chatjs-room", because we have only one room.
return ROOM_ID_STUB;
}

/// <summary>
/// Broadcasts to all users in the same room the new users list
/// </summary>
private void BroadcastUsersList()
{
var myRoomId = this.GetMyRoomId();
var connectionIds = new List<string>();
lock (connections)
{
if (connections.ContainsKey(myRoomId))
connectionIds = connections[myRoomId].Keys.SelectMany(userId => connections[myRoomId][userId]).ToList();
}

// gets the current room user's list

// this is STUB. You would normally go to the database to get the real room users
var dbRoomUsers = dbUsersStub.Where(u => u.TenancyId == myRoomId).OrderBy(u => u.FullName).ToList();
var usersList = dbRoomUsers.Select(u => this.GetChatUserFromDbUserId(u.Id)).ToList();

foreach (var connectionId in connectionIds)
this.Clients.Client(connectionId).usersListChanged(usersList);
}

private DbChatMessageStub PersistMessage(int otherUserId, string message)
{
var myUserId = this.GetMyUserId();

// this is STUB. Normally you would go to the real database to get the my user and the other user
var myUser = dbUsersStub.FirstOrDefault(u => u.Id == myUserId);
var otherUser = dbUsersStub.FirstOrDefault(u => u.Id == otherUserId);

if (myUser == null || otherUser == null)
return null;

var dbChatMessage = new DbChatMessageStub()
{
Date = DateTime.UtcNow,
Message = message,
UserFromId = myUserId,
UserToId = otherUserId,
TenancyId = myUser.TenancyId
};

// this is STUB. Normally you would add the dbMessage to the real database
dbChatMessagesStub.Add(dbChatMessage);

// normally you would save the database changes
//this.db.SaveChanges();

return dbChatMessage;
}

/// <summary>
/// Returns the message history
/// </summary>
public List<ChatMessage> GetMessageHistory(int otherUserId)
{
var myUserId = this.GetMyUserId();
// this is STUB. Normally you would go to the real database to get the messages
var dbMessages = dbChatMessagesStub
.Where(
m =>
(m.UserToId == myUserId && m.UserFromId == otherUserId) ||
(m.UserToId == otherUserId && m.UserFromId == myUserId))
.OrderByDescending(m => m.Date).Take(30).ToList();

dbMessages.Reverse();
return dbMessages.Select(m => this.GetChatMessage(m, null)).ToList();
}

/// <summary>
/// Sends a message to a particular user
/// </summary>
public void SendMessage(int otherUserId, string message, string clientGuid)
{
var myUserId = this.GetMyUserId();
var myRoomId = this.GetMyRoomId();


var dbChatMessage = PersistMessage(otherUserId, message);
var connectionIds = new List<string>();
lock (connections)
{
if (connections[myRoomId].ContainsKey(otherUserId))
connectionIds.AddRange(connections[myRoomId][otherUserId]);
if (connections[myRoomId].ContainsKey(myUserId))
connectionIds.AddRange(connections[myRoomId][myUserId]);
}
foreach (var connectionId in connectionIds)
this.Clients.Client(connectionId).sendMessage(this.GetChatMessage(dbChatMessage, clientGuid));
}

/// <summary>
/// Sends a typing signal to a particular user
/// </summary>
public void SendTypingSignal(int otherUserId)
{
var myUserId = this.GetMyUserId();
var myRoomId = this.GetMyRoomId();

var connectionIds = new List<string>();
lock (connections)
{
if (connections[myRoomId].ContainsKey(otherUserId))
connectionIds.AddRange(connections[myRoomId][otherUserId]);
}
foreach (var connectionId in connectionIds)
this.Clients.Client(connectionId).sendTypingSignal(this.GetUserInfo(myUserId));
}

public override Task OnConnected()
{
var myRoomId = this.GetMyRoomId();
var myUserId = this.GetMyUserId();

lock (connections)
{
if (!connections.ContainsKey(myRoomId))
connections[myRoomId] = new Dictionary<int, List<string>>();

if (!connections[myRoomId].ContainsKey(myUserId))
connections[myRoomId][myUserId] = new List<string>();

connections[myRoomId][myUserId].Add(this.Context.ConnectionId);
}

this.BroadcastUsersList();

return base.OnConnected();
}

public override Task OnDisconnected()
{
var myRoomId = this.GetMyRoomId();
var myUserId = this.GetMyUserId();

lock (connections)
{
if (connections.ContainsKey(myRoomId))
if (connections[myRoomId].ContainsKey(myUserId))
if (connections[myRoomId][myUserId].Contains(this.Context.ConnectionId))
{
connections[myRoomId][myUserId].Remove(this.Context.ConnectionId);
if (!connections[myRoomId][myUserId].Any())
{
connections[myRoomId].Remove(myUserId);
Task.Factory.StartNew(() =>
{
// this will run in separate thread.
// If the user is away for more than 10 seconds it will be removed from
// the room.
// In a normal situation this wouldn't be done because normally the users in a
// chat room are fixed, like when you have 1 chat room for each tenancy
Thread.Sleep(10000);
if (!connections[myRoomId].ContainsKey(myUserId))
{
var myDbUser = dbUsersStub.FirstOrDefault(u => u.Id == myUserId);
if (myDbUser != null)
{
dbUsersStub.Remove(myDbUser);
this.BroadcastUsersList();
}
}
});
}
}
}

return base.OnDisconnected();
}
}

最佳答案

private void BroadcastUsersList()
{
var myRoomId = this.GetMyRoomId();
var connectionIds = new List<string>();
lock (connections)
{
if (connections.ContainsKey(myRoomId))
connectionIds = connections[myRoomId].Keys.SelectMany(userId => connections[myRoomId][userId]).ToList();
}


List<UserSite> dbRoomUsers = new List<UserSite>();
int myId = GetMyUserId();
List<Int>listFriendId = getListUserIdFriendOfUser(myId);
listFriendId.Add(myId);
foreach (var item in dbUsersStub)
{
if (listFriendId.Contains(item.Id))
dbRoomUsers.Add(item);
}
var usersList = dbRoomUsers.Select(u => this.GetChatUserFromDbUserId(u.Id)).ToList();

foreach (var connectionId in connectionIds)
this.Clients.Client(connectionId).usersListChanged(usersList);
}

关于asp.net-mvc - 使用 chatjs.net SignalR MVC 聊天的好友列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18151902/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com