/// <summary> /// Send a message to all connections except one /// </summary> /// <param name="message">The message to send</param> /// <param name="method">How to deliver the message</param> /// <param name="except">Don't send to this particular connection</param> /// <param name="sequenceChannel">Which sequence channel to use for the message</param> public void SendToAll( NetOutgoingMessage message, NetConnection?except, NetDeliveryMethod method, int sequenceChannel) { if (message == null) { throw new ArgumentNullException(nameof(message)); } var all = NetConnectionListPool.GetConnections(this); if (all == null) { if (!message._isSent) { Recycle(message); } return; } try { if (except != null) { all.Remove(except); } SendMessage(message, all, method, sequenceChannel); } finally { NetConnectionListPool.Return(all); } }
/// <summary> /// Streams a message to a list of connections. /// </summary> /// <param name="message">The message to stream.</param> /// <param name="recipients">The list of recipients to send to.</param> /// <param name="sequenceChannel">Sequence channel within <see cref="NetDeliveryMethod.ReliableOrdered"/>.</param> public async ValueTask <NetSendResult> StreamMessageAsync( PipeReader message, IEnumerable <NetConnection?> recipients, int sequenceChannel, CancellationToken cancellationToken = default) { List <NetConnection> recipientList = NetConnectionListPool.Rent(recipients); try { if (recipientList.Count == 0) { return(NetSendResult.NoRecipients); } if (recipientList.Count > 1) { throw new NotImplementedException("The method can only send to one recipient at the time."); } return(await SendFragmentedMessageAsync(message, recipientList[0], sequenceChannel, cancellationToken)); } finally { NetConnectionListPool.Return(recipientList); } }
/// <summary> /// Send a message to a specific connection. /// </summary> /// <param name="message">The message to send</param> /// <param name="recipient">The recipient connection</param> /// <param name="method">How to deliver the message</param> /// <param name="sequenceChannel">Sequence channel within the delivery method</param> public NetSendResult SendMessage( NetOutgoingMessage message, NetConnection recipient, NetDeliveryMethod method, int sequenceChannel) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (recipient == null) { throw new ArgumentNullException(nameof(recipient)); } NetConstants.AssertValidDeliveryChannel( method, sequenceChannel, nameof(method), nameof(sequenceChannel)); message.AssertNotSent(nameof(message)); message._isSent = true; bool suppressFragmentation = (method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.UnreliableSequenced) && Configuration.UnreliableSizeBehaviour != NetUnreliableSizeBehaviour.NormalFragmentation; if (suppressFragmentation || message.GetEncodedSize() <= recipient.CurrentMTU) { Interlocked.Increment(ref message._recyclingCount); return(recipient.EnqueueMessage(message, method, sequenceChannel).Result); } else { // message must be fragmented! if (recipient.Status != NetConnectionStatus.Connected) { return(NetSendResult.FailedNotConnected); } List <NetConnection> recipients = NetConnectionListPool.Rent(1); try { recipients.Add(recipient); return(SendFragmentedMessage(message, recipients, method, sequenceChannel)); } finally { NetConnectionListPool.Return(recipients); } } }