2014-12-25 3 views
1

Я хотел бы написать простой чат по принципу omegle.com. Я написал, что если пользователь входит в сервер и пустая очередь создает новую группу и попадает в очередь. Когда другой человек входит, он соединяется с этим в очереди. Вот мой код:Частный чат с SignalR - поговорить с незнакомцами

public class UserGroup 
{   
    public string GroupName { get; set; } 
} 

public class ChatHub : Hub 
{ 
    public static Queue<UserGroup> Users = new Queue<UserGroup>(); 
    public static string Group { get; set; } 

    public Task JoinGroup(string groupName) 
    { 
     return Groups.Add(Context.ConnectionId, groupName); 
    } 

    public override System.Threading.Tasks.Task OnConnected() 
    { 
     if(Users.Count == 0) 
     { 
      var user = new UserGroup { GroupName = Context.ConnectionId }; 
      Users.Enqueue(user); 
      Group = user.GroupName; 
      JoinGroup(user.GroupName); 

     } 
     else 
     { 
      JoinGroup(Users.Peek().GroupName); 
      Group = Users.Peek().GroupName; 
      Users.Dequeue(); 
     } 
     return base.OnConnected(); 
    } 
    public void SayHello(string name, string helloMsg) 
    { 
     Clients.Caller.Hello(name, helloMsg); 

    } 

    public void Send(string msg) 
    { 

     Clients.Group(Group).SendMessage(msg); 
    } 

} 

К сожалению, когда я подключаюсь к кому-то другому, все ломается и не создает новую группу для новых людей. Все статические данные, но, к сожалению, не SignalR позволяет иначе. У вас есть идея, как обойти это?

ответ

0

Я не думаю, что вам нужна очередь или использовать группы в этом сценарии. Самое простое решение - отправить идентификатор клиента незнакомца другому клиенту. Вы должны включить блокировку, потому что доступ к общим состоянием из различных экземпляров ступиц:

  1. Создайте новый проект веб-приложения ASP.NET MVC и выбрать в качестве основы.

  2. Добавить Microsoft.AspNet.SignalR и knockoutjs nuget пакеты и обновить все пакеты.

  3. Текущая версия SignalR требует, чтобы вы добавить Startup класс:

    public class Startup 
    { 
        public void Configuration(IAppBuilder app) 
        { 
         app.MapSignalR(); 
        } 
    } 
    
  4. Добавить класс хаб:

    public class ChatHub : Hub 
    { 
        private static string waitingUser; 
        private static readonly object SyncLock = new object(); 
    
        public void SendMessage(string text, string clientId) 
        { 
         this.Clients.Client(clientId).addMessage(text); 
        } 
    
        public override Task OnConnected() 
        { 
         var newUser = this.Context.ConnectionId; 
         string otherUser; 
    
         lock (SyncLock) 
         { 
          if (waitingUser == null) 
          { 
           waitingUser = newUser; 
           return base.OnConnected(); 
          } 
    
          otherUser = waitingUser; 
          waitingUser = null; 
         } 
    
         this.Clients.Caller.startChat(otherUser); 
         this.Clients.Client(otherUser).startChat(newUser); 
    
         return base.OnConnected(); 
        } 
    } 
    
  5. Наконец, добавьте следующий код в ваш взгляд:

    @{ 
        ViewBag.Title = "Chat wit a Stranger"; 
    } 
    
    <h1>Chat with a Stranger</h1> 
    
    <div data-bind="foreach: messages"> 
        <div data-bind="text: $data"></div> 
    </div> 
    
    <hr/> 
    
    <form data-bind="submit: send, visible: connected"> 
        <input type="text" data-bind="value: text" /> 
        <button type="submit">Send</button> 
    </form> 
    
    <script src="~/Scripts/knockout-3.2.0.debug.js"></script> 
    <script src="~/Scripts/jquery-2.1.1.js"></script> 
    <script src="~/Scripts/jquery.signalR-2.1.2.js"></script> 
    <script src="~/signalr/hubs"></script> 
    
    <script> 
    
        var hub = $.connection.chatHub; 
    
        var vm = { 
         otherUser: "", 
         messages: ko.observableArray(["Waiting for a stranger..."]), 
         connected: ko.observable(false), 
         text: ko.observable(""), 
    
         send: function() { 
          var text = vm.text(); 
          if (text.length == 0) return; 
          hub.server.sendMessage(text, vm.otherUser); 
          vm.messages.push("You: " + text); 
          vm.text(""); 
         }, 
    
         addMessage: function(text) { 
          vm.messages.push("Stranger: " + text); 
         }, 
    
         startChat: function (otherUser) { 
          vm.otherUser = otherUser; 
          vm.messages(["A stranger has connected. Say hello!"]); 
          vm.connected(true); 
         } 
        } 
    
        ko.applyBindings(vm); 
    
        hub.client.startChat = vm.startChat; 
        hub.client.addMessage = vm.addMessage; 
    
        $.connection.hub.start(); 
    
    </script> 
    
Смежные вопросы