/// <summary> /// Send a message to this exact same netpeer (loopback). /// </summary> public void SendUnconnectedToSelf(NetOutgoingMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } message.AssertNotSent(nameof(message)); if (Socket == null) { throw new InvalidOperationException("No socket bound."); } message._messageType = NetMessageType.Unconnected; message._isSent = true; if (!Configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData)) { return; // dropping unconnected message since it's not enabled for receiving } var om = CreateIncomingMessage(NetIncomingMessageType.UnconnectedData); om.Write(message); om.IsFragment = false; om.ReceiveTime = NetTime.Now; om.SenderConnection = null; om.SenderEndPoint = Socket.LocalEndPoint as IPEndPoint; LidgrenException.Assert(om.BitLength == message.BitLength); ReleaseMessage(om); }
/// <summary> /// Send a message to a list of connections. /// </summary> /// <param name="message">The message to send</param> /// <param name="recipients">The list of recipients to send to</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, IEnumerable <NetConnection?> recipients, NetDeliveryMethod method, int sequenceChannel) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } NetConstants.AssertValidDeliveryChannel( method, sequenceChannel, nameof(method), nameof(sequenceChannel)); message.AssertNotSent(nameof(message)); message._isSent = true; int mtu = GetMTU(recipients, out int recipientCount); if (recipientCount == 0) { Recycle(message); return(NetSendResult.NoRecipients); } int length = message.GetEncodedSize(); if (length <= mtu) { Interlocked.Add(ref message._recyclingCount, recipientCount); var retval = NetSendResult.Sent; foreach (NetConnection?conn in recipients.AsListEnumerator()) { if (conn == null) { continue; } NetSendResult result = conn.EnqueueMessage(message, method, sequenceChannel).Result; if (result > retval) { retval = result; // return "worst" result } } return(retval); } else { // message must be fragmented! return(SendFragmentedMessage(message, recipients, method, sequenceChannel)); } }
/// <summary> /// Send a message to an unconnected host. /// </summary> public void SendUnconnectedMessage(NetOutgoingMessage message, IPEndPoint recipient) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (recipient == null) { throw new ArgumentNullException(nameof(recipient)); } message.AssertNotSent(nameof(message)); AssertValidUnconnectedLength(message); SendUnconnectedMessageCore(message, recipient); }
/// <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); } } }
/// <summary> /// Send a message to an unconnected host. /// </summary> public void SendUnconnectedMessage(NetOutgoingMessage message, ReadOnlySpan <char> host, int port) { if (message == null) { throw new ArgumentNullException(nameof(message)); } message.AssertNotSent(nameof(message)); AssertValidUnconnectedLength(message); IPAddress?address = NetUtility.Resolve(host); if (address == null) { throw new LidgrenException("Failed to resolve " + host.ToString()); } IPEndPoint recipient = new(address, port); SendUnconnectedMessageCore(message, recipient); }
/// <summary> /// Send a message to an unconnected recipients. /// </summary> public void SendUnconnectedMessage(NetOutgoingMessage message, IEnumerable <IPEndPoint?> recipients) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } AssertValidUnconnectedLength(message); message.AssertNotSent(nameof(message)); message._messageType = NetMessageType.Unconnected; message._isSent = true; int recipientCount = 0; foreach (IPEndPoint?recipient in recipients.AsListEnumerator()) { if (recipient != null) { recipientCount++; } } Interlocked.Add(ref message._recyclingCount, recipientCount); foreach (IPEndPoint?endPoint in recipients.AsListEnumerator()) { if (endPoint != null) { UnsentUnconnectedMessages.Enqueue((endPoint, message)); } } }