/// <summary> /// Check new connections from other world /// </summary> public async Task CheckNewConnectionAsync() { var newConnection = await _tcpListener.AcceptTcpClientAsync(); var connectionUser = new ConnectionModel { TcpSocket = newConnection }; var connection = new Connection { User = connectionUser }; CurrentConnections.Add(connection); connection.OnReceivedMessage += Connection_OnReceivedMessage;; connection.OnDisconnected += Connection_OnDisconnected; connection.OnReceivedCommand += Connection_OnReceivedCommand; connection.OnReceivedVideoFrame += Connection_OnReceivedVideoFrame; connection.OnStartSendingVideo += Connection_OnStartSendingVideo; connection.OnStopSendingVideo += Connection_OnStopSendingVideo; connection.StartReceiveResponses(); }
/// <summary> /// Performs execution of the command /// </summary> protected override void DoProcessRecord() { CurrentConnections.Set( CurrentConnections.Server, null ); }
public void CloseGame(string connectionId) { var user = CurrentConnections.FirstOrDefault(x => x.ConnectionId == connectionId); CurrentConnections.Remove(user); Clients.Caller.leaveGame(); }
/// <summary> /// Performs execution of the command /// </summary> protected override void DoProcessRecord() { CurrentConnections.Set( CurrentConnections.Server, CurrentConnections.Collection, CurrentConnections.Project, null ); }
public int GetNumberOfGroups() { var groups = 0; while (ExcludedPrograms.Any()) { var startingProgram = ExcludedPrograms.First(); var group = startingProgram.GetExtendedConnections(this).ToList(); CurrentConnections.Clear(); groups++; } return(groups); }
/// <inheritdoc/> protected override void DoProcessRecord() { var srv = this.GetServer(); srv.Connect(); CurrentConnections.Set(srv); this.Log($"Connected to {srv.Uri}, ID {srv.ServerId}, as {srv.AuthorizedIdentity.DisplayName}"); if (Passthru) { WriteObject(srv); } }
/// <summary> /// Performs execution of the command /// </summary> protected override void DoProcessRecord() { var tpc = this.GetCollection(); tpc.Connect(); var srv = tpc.ConfigurationServer; CurrentConnections.Set(srv, tpc); this.Log($"Connected to {tpc.Uri}, ID {tpc.ServerId}, as '{tpc.AuthorizedIdentity.DisplayName}'"); if (Passthru) { WriteObject(tpc); } }
/// <summary> /// Method which send video frame from one to another user /// </summary> public async Task <bool> SendVideoFrameAsync(ConversationModel conversationData, Connection initiator) { var targetConnection = CurrentConnections.FirstOrDefault(connection => connection.User.Id == conversationData.Target.Id); if (targetConnection == null) { return(false); } Packet videoPacket = new Packet { ActionState = ActionStates.Video, Conversation = conversationData }; return(await SendConversationResponseAsync(videoPacket, targetConnection, initiator)); }
/// <summary> /// Performs execution of the command /// </summary> protected override void DoProcessRecord() { var(tpc, tp, t) = this.GetCollectionProjectAndTeam(); CurrentConnections.Set(tpc.ConfigurationServer, tpc, tp, t); // TODO: //this.Log($"Adding '{tp.Name} to the MRU list"); //_SetMru "Server" - Value(srv.Uri) //_SetMru "Collection" - Value(tpc.Uri) //_SetMru "Project" - Value(tp.Name) this.Log($"Connected to '{t.Name}'"); if (Passthru) { WriteObject(tp); } }
public async Task SendNotificationAsync(Guid targetId, NotificationModel notification) { var target = CurrentConnections.FirstOrDefault(c => c.User.Id == targetId); if (target == null) { return; } Packet commandResultPacket = new Packet { ActionState = ActionStates.Notification, Notification = notification }; //Add notification in query if (!await NetHelper.SendDataAsync(target?.User?.TcpSocket, commandResultPacket)) { CurrentNotifications.Add(targetId, notification); } }
public void Send(string name) { string connectionId = Context.ConnectionId; string userName = name; if (userName != null && userName.Length >= 1) { var u = new Users() { ConnectionId = connectionId, UserName = userName }; if (u.ConnectionId != null && !CurrentConnections.Contains(u)) { CurrentConnections.Add(u); } } //Clients.AllExcept(CurrentConnections.Where(x => x.ConnectionId == Context.ConnectionId).Select(x => x.ConnectionId).FirstOrDefault()); Clients.All.broadcastMessage(name); Clients.Caller.renderGame(); }
/// <devdoc> /// <para> /// Used by the ServicePoint to find a free or new Connection /// for use in making Requests. Under NTLM and Negotiate requests, /// this function depricates itself and switches the object over to /// using a new code path (see FindConnectionAuthenticationGroup). /// </para> /// </devdoc> internal Connection FindConnection(HttpWebRequest request, string connName, out bool forcedsubmit) { Connection leastbusyConnection = null; Connection newConnection = null; bool freeConnectionsAvail = false; forcedsubmit = false; if (m_AuthenticationGroup || request.LockConnection) { m_AuthenticationGroup = true; return(FindConnectionAuthenticationGroup(request, connName)); } GlobalLog.Print("ConnectionGroup::FindConnection [" + connName + "] m_ConnectionList.Count:" + m_ConnectionList.Count.ToString()); lock (m_ConnectionList) { // // go through the list of open connections to this service point and pick the connection as follows: // - free connection // - if there is no free connection and if we are under connection limit, create new connection // - pick the least busy connection which does not have non-keep alive request pipelined // - pick the least busy connection which may have non-keep alive request pipelined // If we pick the connection with non keep-alive request pipelined on it, we set forcedsubmit to true. // This will make sure that we don't start the request immediately and it gets queued on the connection. // int minBusyCount = Int32.MaxValue; bool foundLiveConnection = false; foreach (Connection currentConnection in m_ConnectionList) { GlobalLog.Print("ConnectionGroup::FindConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString()); bool useThisConnection = false; if (foundLiveConnection) { useThisConnection = (!currentConnection.NonKeepAliveRequestPipelined && minBusyCount > currentConnection.BusyCount); } else { useThisConnection = (!currentConnection.NonKeepAliveRequestPipelined || minBusyCount > currentConnection.BusyCount); } if (useThisConnection) { leastbusyConnection = currentConnection; minBusyCount = currentConnection.BusyCount; if (!foundLiveConnection) { foundLiveConnection = !currentConnection.NonKeepAliveRequestPipelined; } else { GlobalLog.Assert(!currentConnection.NonKeepAliveRequestPipelined, "Connection.NonKeepAliveRequestPipelined == false|Non keep-alive request has been pipelined on this connection."); } if (foundLiveConnection && minBusyCount == 0) { freeConnectionsAvail = true; break; } } } // // If there is NOT a Connection free, then we allocate a new Connection // if (!freeConnectionsAvail && CurrentConnections < ConnectionLimit) { // // If we can create a new connection, then do it, // this may have complications in pipeling because // we may wish to optimize this case by actually // using existing connections, rather than creating new ones // // Note: this implicately results in a this.Associate being called. // GlobalLog.Print("ConnectionGroup::FindConnection [returning new Connection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString()); newConnection = new Connection(this); forcedsubmit = false; } else { // // All connections are busy, use the least busy one // GlobalLog.Print("ConnectionGroup::FindConnection [returning leastbusyConnection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString()); GlobalLog.Assert(leastbusyConnection != null, "Connect.leastbusyConnection != null|All connections have BusyCount equal to Int32.MaxValue."); newConnection = leastbusyConnection; forcedsubmit = !foundLiveConnection; } newConnection.MarkAsReserved(); } return(newConnection); }
/// <devdoc> /// <para> /// Attempts to match a request with a connection, if a connection is unassigned ie not locked with /// a request, then the least busy connections is returned in "leastbusyConnection." If the /// connection limit allows, and all connections are busy, a new one is allocated and returned. /// /// RETURNS: a Connection shown to match a previously locked Request/Connection (OTHERWISE) /// leasebusyConnection - will contain a newly allocated Connection or least Busy one /// suiteable for requests. /// /// NOTE: For Whidbey: try to integrate this code into FindConnection() /// </para> /// </devdoc> private Connection FindMatchingConnection(HttpWebRequest request, string connName, out Connection leastbusyConnection) { int minBusyCount = Int32.MaxValue; bool freeConnectionsAvail = false; leastbusyConnection = null; lock (m_ConnectionList) { // // go through the list of open connections to this service point and pick the first free one or, // if none is free, pick the least busy one. Skip all connections with non keep-alive request pipelined. // minBusyCount = Int32.MaxValue; foreach (Connection currentConnection in m_ConnectionList) { GlobalLog.Print("ConnectionGroup::FindMatchingConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString()); if (currentConnection.LockedRequest == request) { leastbusyConnection = currentConnection; return(currentConnection); } GlobalLog.Print("ConnectionGroup::FindMatchingConnection: lockedRequest# " + ((currentConnection.LockedRequest == null) ? "null" : currentConnection.LockedRequest.GetHashCode().ToString())); if (!currentConnection.NonKeepAliveRequestPipelined && currentConnection.BusyCount < minBusyCount && currentConnection.LockedRequest == null) { leastbusyConnection = currentConnection; minBusyCount = currentConnection.BusyCount; if (minBusyCount == 0) { freeConnectionsAvail = true; } } } // // If there is NOT a Connection free, then we allocate a new Connection // if (!freeConnectionsAvail && CurrentConnections < ConnectionLimit) { // // If we can create a new connection, then do it, // this may have complications in pipeling because // we may wish to optimize this case by actually // using existing connections, rather than creating new ones // // Note: this implicately results in a this.Associate being called. // GlobalLog.Print("ConnectionGroup::FindMatchingConnection [returning new Connection] CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString()); leastbusyConnection = new Connection(this); } } return(null); // only if we have a locked Connection that matches can return non-null }
/// <devdoc> /// <para> /// Attempts to match a request with a connection, if a connection is unassigned ie not locked with /// a request, then the least busy connections is returned in "leastbusyConnection." If the /// connection limit allows, and all connections are busy, a new one is allocated and returned. /// /// RETURNS: a Connection shown to match a previously locked Request/Connection (OTHERWISE) /// leasebusyConnection - will contain a newly allocated Connection or least Busy one /// suiteable for requests. /// /// NOTE: For Whidbey: try to integrate this code into FindConnection() /// </para> /// </devdoc> private Connection FindMatchingConnection(HttpWebRequest request, string connName, out Connection leastbusyConnection) { int minBusyCount = Int32.MaxValue; bool freeConnectionsAvail = false; leastbusyConnection = null; lock (m_ConnectionList) { // // go through the list of open connections to this service point and pick // the first empty one or, if none is empty, pick the least busy one. // bool completed; do { minBusyCount = Int32.MaxValue; completed = true; // by default, only once through the outer loop foreach (WeakReference currentConnectionReference in m_ConnectionList) { Connection currentConnection = null; if (currentConnectionReference != null) { currentConnection = currentConnectionReference.Target as Connection; } // // If the weak reference is alive, see if its not busy, // otherwise make sure to remove it from the list // if (currentConnection != null) { GlobalLog.Print("ConnectionGroup::FindConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString()); if (currentConnection.LockedRequest == request) { leastbusyConnection = currentConnection; return(currentConnection); } GlobalLog.Print("ConnectionGroup::FindConnection: lockedRequest# " + ((currentConnection.LockedRequest == null) ? "null" : currentConnection.LockedRequest.GetHashCode().ToString())); if (currentConnection.BusyCount < minBusyCount && currentConnection.LockedRequest == null) { leastbusyConnection = currentConnection; minBusyCount = currentConnection.BusyCount; if (minBusyCount == 0) { freeConnectionsAvail = true; } } } else { m_ConnectionList.Remove(currentConnectionReference); completed = false; // now start iterating again because we changed the ArrayList break; } } } while (!completed); // // If there is NOT a Connection free, then we allocate a new Connection // if (!freeConnectionsAvail && CurrentConnections < InternalConnectionLimit) { // // If we can create a new connection, then do it, // this may have complications in pipeling because // we may wish to optimize this case by actually // using existing connections, rather than creating new ones // // Note: this implicately results in a this.Associate being called. // GlobalLog.Print("ConnectionGroup::FindConnection [returning new Connection] CurrentConnections:" + CurrentConnections.ToString() + " InternalConnectionLimit:" + InternalConnectionLimit.ToString()); leastbusyConnection = new Connection( this, m_ServicePoint, m_IPAddress, m_ServicePoint.ProtocolVersion, m_ServicePoint.SupportsPipelining ); } } return(null); // only if we have a locked Connection that matches can return non-null }
/// <summary> /// Performs execution of the command /// </summary> protected override void DoProcessRecord() { CurrentConnections.Reset(); }
/// <summary> /// Event which invoke when server receive new response from other world /// </summary> private void Connection_OnDisconnected(Connection sender, ReceivedPacketEventsArgs e) { CloseConnection(sender); CurrentConnections.Remove(sender); }
/// <devdoc> /// <para> /// Used by the ServicePoint to find a free or new Connection /// for use in making Requests. Under NTLM and Negotiate requests, /// this function depricates itself and switches the object over to /// using a new code path (see FindConnectionAuthenticationGroup). /// </para> /// </devdoc> internal Connection FindConnection(HttpWebRequest request, string connName) { Connection leastbusyConnection = null; Connection newConnection = null; bool freeConnectionsAvail = false; if (m_AuthenticationGroup || request.LockConnection) { m_AuthenticationGroup = true; return(FindConnectionAuthenticationGroup(request, connName)); } GlobalLog.Print("ConnectionGroup::FindConnection [" + connName + "] m_ConnectionList.Count:" + m_ConnectionList.Count.ToString()); lock (m_ConnectionList) { // // go through the list of open connections to this service point and pick // the first empty one or, if none is empty, pick the least busy one. // int minBusyCount = Int32.MaxValue; foreach (Connection currentConnection in m_ConnectionList) { GlobalLog.Print("ConnectionGroup::FindConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString()); if (currentConnection.BusyCount < minBusyCount) { leastbusyConnection = currentConnection; minBusyCount = currentConnection.BusyCount; if (minBusyCount == 0) { freeConnectionsAvail = true; break; } } } // // If there is NOT a Connection free, then we allocate a new Connection // if (!freeConnectionsAvail && CurrentConnections < ConnectionLimit) { // // If we can create a new connection, then do it, // this may have complications in pipeling because // we may wish to optimize this case by actually // using existing connections, rather than creating new ones // // Note: this implicately results in a this.Associate being called. // GlobalLog.Print("ConnectionGroup::FindConnection [returning new Connection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString()); newConnection = new Connection(this); } else { // // All connections are busy, use the least busy one // GlobalLog.Print("ConnectionGroup::FindConnection [returning leastbusyConnection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString()); GlobalLog.Assert(leastbusyConnection != null, "Connect.leastbusyConnection != null|All connections have BusyCount equal to Int32.MaxValue."); newConnection = leastbusyConnection; } } return(newConnection); }
/// <devdoc> /// <para> /// Used by the ServicePoint to find a free or new Connection /// for use in making Requests. /// </para> /// </devdoc> public Connection FindConnection(string connName) { Connection leastbusyConnection = null; Connection newConnection = null; bool freeConnectionsAvail = false; GlobalLog.Print("ConnectionGroup::FindConnection [" + connName + "] m_ConnectionList.Count:" + m_ConnectionList.Count.ToString()); lock (m_ConnectionList) { // // go through the list of open connections to this service point and pick // the first empty one or, if none is empty, pick the least busy one. // bool completed; do { int minBusyCount = Int32.MaxValue; completed = true; // by default, only once through the outer loop foreach (WeakReference currentConnectionReference in m_ConnectionList) { Connection currentConnection = null; if (currentConnectionReference != null) { currentConnection = currentConnectionReference.Target as Connection; } // // If the weak reference is alive, see if its not busy, // otherwise make sure to remove it from the list // if (currentConnection != null) { GlobalLog.Print("ConnectionGroup::FindConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString()); if (currentConnection.BusyCount < minBusyCount) { leastbusyConnection = currentConnection; minBusyCount = currentConnection.BusyCount; if (minBusyCount == 0) { freeConnectionsAvail = true; break; } } } else { m_ConnectionList.Remove(currentConnectionReference); completed = false; // now start iterating again because we changed the ArrayList break; } } } while (!completed); // // If there is NOT a Connection free, then we allocate a new Connection // if (!freeConnectionsAvail && CurrentConnections < InternalConnectionLimit) { // // If we can create a new connection, then do it, // this may have complications in pipeling because // we may wish to optimize this case by actually // using existing connections, rather than creating new ones // // Note: this implicately results in a this.Associate being called. // GlobalLog.Print("ConnectionGroup::FindConnection [returning new Connection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " InternalConnectionLimit:" + InternalConnectionLimit.ToString()); newConnection = new Connection( this, m_ServicePoint, m_IPAddress, m_ServicePoint.ProtocolVersion, m_ServicePoint.SupportsPipelining); } else { // // All connections are busy, use the least busy one // GlobalLog.Print("ConnectionGroup::FindConnection [returning leastbusyConnection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " InternalConnectionLimit:" + InternalConnectionLimit.ToString()); GlobalLog.Assert(leastbusyConnection != null, "Connect.leastbusyConnection != null", "All connections have BusyCount equal to Int32.MaxValue"); newConnection = leastbusyConnection; } } return(newConnection); }
protected override IEnumerable <Connection> DoGetItems() { var connectionType = GetParameter <ClientScope>("ConnectionType").ToString(); var connection = GetParameter <object>(connectionType); VssConnection result = null; while (result == null) { switch (connection) { case Connection conn: { result = conn.InnerConnection; break; } case VssConnection conn: { result = conn; break; } case null: { Logger.Log($"Get currently connected {connectionType}"); result = ((Connection)CurrentConnections.Get(connectionType))?.InnerConnection; if (result == null) { yield break; } break; } case Uri uri: { Logger.Log($"Get {connectionType} referenced by URL '{uri}'"); result = new VssConnection(uri, Provider.GetDataService <VssCredentials>(Cmdlet, new{ Url = uri }).GetItem()); break; } case string uri when Uri.IsWellFormedUriString(uri, UriKind.Absolute): { connection = new Uri(uri); continue; } case string name: { connection = VssConnectionHelper.GetOrganizationUrlAsync(name).Result; continue; } default: { throw new Exception($"Invalid or non-existent {connectionType} {connection}."); } } } if (connectionType.Equals("Server")) { result = (new Connection(result)).ConfigurationServer; } yield return(new Connection(result)); }
/// <summary> /// Event which invoke when server receive new command from other world /// </summary> private async void Connection_OnReceivedCommand(Connection sender, ReceivedCommandEventsArgs e) { CommandModel commandResult = null; switch (e.Command.CommandType) { case CommandTypes.Authorization: DBHelper.TryAuthorizationUser(JObject.Parse(e.Command.Data), out commandResult); await SendCommandResultAsync(sender, commandResult); break; case CommandTypes.Registration: DBHelper.TryRegisterUser(JObject.Parse(e.Command.Data), out commandResult); await SendCommandResultAsync(sender, commandResult); break; case CommandTypes.UserInfo: var result = DBHelper.GetUserInfo(JObject.Parse(e.Command.Data)); //Set Id to sender connection if (result.Item2 != Guid.Empty) { var recentConnection = CurrentConnections.FirstOrDefault(cc => cc.User.TcpSocket == sender.User.TcpSocket); if (recentConnection != null) { recentConnection.User.Id = result.Item2; } var notification = CurrentNotifications.FirstOrDefault(n => n.Key == recentConnection.User.Id).Value; //Check that have user missed notification or not if (notification != null) { await SendNotificationAsync(recentConnection.User.Id, notification); CurrentNotifications.Remove(recentConnection.User.Id); } } await SendCommandResultAsync(sender, result.Item1); break; case CommandTypes.Search: await SendCommandResultAsync(sender, DBHelper.GetSearchResults(JObject.Parse(e.Command.Data))); break; case CommandTypes.GetContacts: await SendCommandResultAsync(sender, DBHelper.GetContacts(JObject.Parse(e.Command.Data))); break; case CommandTypes.SendToApproveContact: result = DBHelper.AddNewContact(JObject.Parse(e.Command.Data)); if (result.Item2 != Guid.Empty) { await SendNotificationAsync(result.Item2, new NotificationModel { NotificationType = NotificationTypes.NewContact }); } await SendCommandResultAsync(sender, result.Item1); break; case CommandTypes.RemoveContact: result = DBHelper.RemoveContact(JObject.Parse(e.Command.Data)); if (result.Item2 != Guid.Empty) { await SendNotificationAsync(result.Item2, new NotificationModel { NotificationType = NotificationTypes.RemoveContact }); } await SendCommandResultAsync(sender, result.Item1); break; case CommandTypes.ApproveContact: result = DBHelper.ApproveContact(JObject.Parse(e.Command.Data)); if (result.Item2 != Guid.Empty) { await SendNotificationAsync(result.Item2, new NotificationModel { NotificationType = NotificationTypes.ApprovedContact }); } await SendCommandResultAsync(sender, result.Item1); break; } }
protected override IEnumerable <Connection> DoGetItems() { var connectionType = GetParameter <ClientScope>("ConnectionType").ToString(); var connection = GetParameter <object>(connectionType); TfsConnection result = null; while (result == null) { switch (connection) { case Connection conn: { result = conn.InnerConnection; break; } case TfsConnection conn: { result = conn; break; } case null: { Logger.Log($"Get currently connected {connectionType}"); yield return((Connection)CurrentConnections.Get(connectionType)); yield break; } case Uri uri: { Logger.Log($"Get {connectionType} referenced by URL '{uri}'"); if (uri.LocalPath.Equals("/")) { Cmdlet.WriteWarning("Connecting to a Team Foundation Server instance without " + $"specifying a collection name may lead to errors. Instead of using {uri} " + "(without a collection name), consider supplying one in the URL, as in e.g. " + $"{uri}DefaultCollection"); } if (connectionType.Equals("Server")) { result = new TfsConfigurationServer(uri, Provider.GetDataService <VssCredentials>(Cmdlet, new{ Url = uri }).GetItem()); } else { result = new TfsTeamProjectCollection(uri, Provider.GetDataService <VssCredentials>(Cmdlet, new{ Url = uri }).GetItem()); } break; } case string uri when Uri.IsWellFormedUriString(uri, UriKind.Absolute): { connection = new Uri(uri); continue; } case string s: { var srv = GetServer(); if (srv.IsHosted) { connection = VssConnectionHelper.GetOrganizationUrlAsync(s); continue; } var configSrv = (TfsConfigurationServer)srv.InnerConnection; var tpcList = configSrv.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None); foreach (var tpc in tpcList.Where(t => t.Resource.DisplayName.IsLike(s))) { var uri = configSrv.GetTeamProjectCollection(new Guid(tpc.Resource.Properties["InstanceId"])).Uri; yield return(connectionType.Equals("Server")? ((TfsConnection) new TfsConfigurationServer(uri, Provider.GetDataService <VssCredentials>(Cmdlet, new{ Url = uri }).GetItem())): ((TfsConnection) new TfsTeamProjectCollection(uri, Provider.GetDataService <VssCredentials>(Cmdlet, new{ Url = uri }).GetItem()))); } yield break; } default: { throw new Exception($"Invalid or non-existent {connectionType} {connection}."); } } } yield return(new Connection(result)); }
/// <summary> /// Send response data to all users which connected to server /// </summary> /// <param name="responseData">Data which need transfer to all clients</param> public void BroadcastResponse(Packet responseData, Connection initiator) { CurrentConnections.ForEach(async connection => await SendConversationResponseAsync(responseData, connection, initiator)); }