Created
April 1, 2013 23:06
-
-
Save aboodysa/5288536 to your computer and use it in GitHub Desktop.
chat hub
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Threading.Tasks; | |
| using System.Web; | |
| using Microsoft.AspNet.SignalR; | |
| using Microsoft.AspNet.SignalR.Hubs; | |
| using SimpleChat.Models; | |
| using System.Collections.Concurrent; | |
| namespace SimpleChat | |
| { | |
| [Authorize] | |
| [HubName("chatHub")] | |
| public class ChatHub2 : Hub | |
| { | |
| private static readonly ConcurrentDictionary<string, User> Users | |
| = new ConcurrentDictionary<string, User>(StringComparer.InvariantCultureIgnoreCase); | |
| ChatContext _db = new ChatContext(); | |
| public void Send(string message) | |
| { | |
| string sender = Context.User.Identity.Name; | |
| //User sender = Context.User.Identity.Name; | |
| string groupName = GetGroupName(sender); | |
| // So, broadcast the sender, too. | |
| //Clients.OthersInGroup(groupName).received(new { sender = sender, message = message, isPrivate = false }); | |
| Clients.Group(groupName).received(new { sender = sender, message = message, isPrivate = false }); | |
| //Clients.All.received(new { sender = sender, message = message, isPrivate = false }); | |
| } | |
| public void SendMessage(string message) | |
| { | |
| string sender = Context.User.Identity.Name; | |
| //User sender = Context.User.Identity.Name; | |
| string groupName = GetGroupName(sender); | |
| // So, broadcast the sender, too. | |
| //Clients.OthersInGroup(groupName).received(new { sender = sender, message = message, isPrivate = false }); | |
| //Clients.Group(groupName).received(new { sender = sender, message = message, isPrivate = false }); | |
| Clients.Group(groupName).received(new { sender = sender, message = message, isPrivate = false }); | |
| } | |
| public void Send(string message, string to) | |
| { | |
| User receiver; | |
| if (Users.TryGetValue(to, out receiver)) | |
| { | |
| User sender = GetUser(Context.User.Identity.Name); | |
| IEnumerable<string> allReceivers; | |
| lock (receiver.ConnectionIds) | |
| { | |
| lock (sender.ConnectionIds) | |
| { | |
| allReceivers = receiver.ConnectionIds.Concat(sender.ConnectionIds); | |
| } | |
| } | |
| foreach (var cid in allReceivers) | |
| { | |
| Clients.Client(cid).received(new { sender = sender.Name, message = message, isPrivate = true }); | |
| } | |
| } | |
| } | |
| public void JoinRoom(string room) | |
| { | |
| // NOTE: this is not persisted - .... | |
| Groups.Add(Context.ConnectionId, room); | |
| } | |
| public void SendMessageToRoom(string room, string message) | |
| { | |
| string sender = Context.User.Identity.Name; | |
| //User sender = Context.User.Identity.Name; | |
| string groupName = GetGroupName(sender); | |
| Clients.Group(room).received(new { sender = sender, message = message, isPrivate = false }); | |
| } | |
| //public Task<int> SendDataAsync() | |
| //{ | |
| // // async ... work... | |
| //} | |
| private String GetGroupName(string userName) | |
| { | |
| return _db.Logins.Single(r => r.Name == userName).GroupName; | |
| } | |
| public override Task OnConnected() | |
| { | |
| string username = Context.User.Identity.Name; | |
| string groupname = this.GetGroupName(username); | |
| Groups.Add(Context.ConnectionId, groupname); | |
| string userName = Context.User.Identity.Name; | |
| string connectionId = Context.ConnectionId; | |
| string groupName = _db.Logins.Single(r => r.Name == userName).GroupName; | |
| var user = Users.GetOrAdd(userName, _ => new User | |
| { | |
| Name = userName, | |
| ConnectionIds = new HashSet<string>(), | |
| GroupName = groupName | |
| }); | |
| lock (user.ConnectionIds) | |
| { | |
| user.ConnectionIds.Add(connectionId); | |
| //Groups.Add(connectionId, groupName); | |
| // // broadcast this to all clients other than the caller | |
| // Clients.AllExcept(user.ConnectionIds.ToArray()).userConnected(userName); | |
| // Or you might want to only broadcast this info if this | |
| // is the first connection of the user | |
| if (user.ConnectionIds.Count == 1) | |
| { | |
| Clients.OthersInGroup(groupName).userConnected(userName); | |
| } | |
| } | |
| //SendMonitoringData("Connected", Context.ConnectionId); | |
| return base.OnConnected(); | |
| } | |
| public override Task OnDisconnected() | |
| { | |
| string userName = Context.User.Identity.Name; | |
| string connectionId = Context.ConnectionId; | |
| string groupName = GetGroupName(userName); | |
| User user; | |
| Users.TryGetValue(userName, out user); | |
| if (user != null) | |
| { | |
| lock (user.ConnectionIds) | |
| { | |
| foreach (string conId in user.ConnectionIds) | |
| { | |
| Groups.Remove(connectionId, groupName); | |
| } | |
| user.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId)); | |
| if (!user.ConnectionIds.Any()) | |
| { | |
| User removedUser; | |
| Users.TryRemove(userName, out removedUser); | |
| // You might want to only broadcast this info if this | |
| // is the last connection of the user and the user actual is | |
| // now disconnected from all connections. | |
| Clients.Group(removedUser.GroupName).userDisconnected(userName); | |
| //Clients.All.userDisconnected(userName); | |
| } | |
| } | |
| } | |
| //SendMonitoringData("Disconnected", Context.ConnectionId); | |
| return base.OnDisconnected(); | |
| } | |
| public override Task OnReconnected() | |
| { | |
| //SendMonitoringData("Reconnected", Context.ConnectionId); | |
| return base.OnReconnected(); | |
| } | |
| private void SendMonitoringData(string eventType, string connection) | |
| { | |
| var context = GlobalHost.ConnectionManager.GetHubContext<MonitorHub>(); | |
| context.Clients.All.newEvent(eventType, connection); | |
| } | |
| protected override void Dispose(bool disposing) | |
| { | |
| _db.Dispose(); | |
| base.Dispose(disposing); | |
| } | |
| public IEnumerable<string> GetConnectedUsers() | |
| { | |
| //User sender = GetUser(Context.User.Identity.Name); | |
| var users = Users.Where(x => | |
| { | |
| lock (x.Value.ConnectionIds) | |
| { | |
| return !x.Value.ConnectionIds.Contains(Context.ConnectionId, StringComparer.InvariantCultureIgnoreCase); | |
| } | |
| }); | |
| return users.Where(x => | |
| { | |
| lock (x.Value.GroupName) | |
| { | |
| return x.Value.GroupName == this.GetGroupName(Context.User.Identity.Name); | |
| } | |
| }).Select(x => x.Key); | |
| } | |
| private User GetUser(string username) | |
| { | |
| User user; | |
| Users.TryGetValue(username, out user); | |
| return user; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment