Thank you for your reply.
If I understand correctly, we should use the same client ID for each
client. And, if that is the case, then this has already been tried,
and the result is that every client after the first throws this
exception:
Unhandled exception. Apache.NMS.NMSException: , ErrorInfo = {
key: invalid-field, value: container-id;
}
---> Apache.NMS.AMQP.Util.NMSProviderError: amqp:invalid-field
at Apache.NMS.AMQP.Util.ExceptionSupport.GetException(Error
amqpErr, String message, Exception e)
at Apache.NMS.AMQP.Provider.Amqp.AmqpConnection.OnClosed(IAmqpObject
sender, Error error)
at Amqp.AmqpObject.NotifyClosed(Error error)
at Amqp.Connection.OnEnded(Error error)
at Amqp.Connection.OnClose(Close close)
at Amqp.Connection.OnFrame(ByteBuffer buffer)
at Amqp.AsyncPump.PumpAsync(UInt32 maxFrameSize, Func`2 onHeader,
Func`2 onBuffer)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object
s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread
threadPoolThread)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at
System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action
innerContinuation, Task innerTask)
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action
action, Boolean allowInlining)
at System.Threading.Tasks.Task.RunContinuations(Object continuationObject)
at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1
task, TResult result)
at Amqp.AsyncPump.ReceiveBufferAsync(Byte[] buffer, Int32 offset,
Int32 count)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object
s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread
threadPoolThread)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at
System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action
innerContinuation, Task innerTask)
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action
action, Boolean allowInlining)
at System.Threading.Tasks.Task.RunContinuations(Object continuationObject)
at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1
task, TResult result)
at Amqp.TcpTransport.TcpSocket.Amqp.IAsyncTransport.ReceiveAsync(Byte[]
buffer, Int32 offset, Int32 count)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object
s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread
threadPoolThread)
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at
System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action
innerContinuation, Task innerTask)
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action
action, Boolean allowInlining)
at System.Threading.Tasks.Task.RunContinuations(Object continuationObject)
at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
at System.Threading.Tasks.TaskCompletionSource`1.TrySetResult(TResult result)
at Amqp.SocketExtensions.Complete[T](Object sender,
SocketAsyncEventArgs args, Boolean throwOnError, T result)
at Amqp.TcpTransport.TcpSocket.<>c.<.ctor>b__6_1(Object s,
SocketAsyncEventArgs a)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__174_0(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading.PortableThreadPool.IOCompletionPoller.Event.Invoke()
at
System.Threading.ThreadPoolTypedWorkItemQueue.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
--- End of inner exception stack trace ---
at Apache.NMS.AMQP.NmsConnection.CreateNmsConnectionInternal(Boolean sync)
at
Apache.NMS.AMQP.Util.Synchronization.TaskExtensions.AwaitRunContinuationAsync(Task
task)
at Apache.NMS.AMQP.NmsConnection.StartAsync()
at Apache.NMS.AMQP.Util.Synchronization.TaskExtensions.GetAsyncResult(Task
task)
at Apache.NMS.AMQP.NmsConnection.Start()
On Tue, Mar 10, 2026 at 4:48 PM Timothy Bish <[email protected]> wrote:
>
> On 3/10/26 19:42, John wrote:
> > Hi Tim,
> >
> > Yes, each client has a unique Client ID. And this has been verified.
> > However, should the Client ID follow a specific pattern?
>
> That's your problem then, you are creating many uniquely identified
> shared subscriptions.
>
> From the JMS specification
>
> "A shared non-durable subscription is identified by a name specified by
> the client and by the client
> identifier if set. If the client identifier was set when the shared
> non-durable subscription was first
> created then a client which subsequently wishes to create a consumer on
> that shared non-durable
> subscription must use the same client identifier."
>
>
> >
> >
> > On Tue, Mar 10, 2026 at 4:17 PM Timothy Bish <[email protected]> wrote:
> >
> >> On 3/10/26 18:51, John wrote:
> >>> Hi,
> >>>
> >>> I have stumbled across an issue that I believe is with Apache.NMS.AMQP
> >>> library. I'm using the latest stable version, 2.4.0, for my .NET C#
> >> service
> >>> for message handling, with the latest Apache Artemis and Apache ActiveMQ
> >>> message brokers.
> >>> Both the web page on Uri Configuration (
> >>>
> >> https://activemq.apache.org/components/nms/providers/amqp/uri-configuration
> >> )
> >>> and the GitHub project (
> >>>
> >> https://github.com/apache/activemq-nms-amqp/blob/main/docs/configuration.md
> >> )
> >>> state that "nms.clientId" should be used in the Connection Uri to
> >> configure
> >>> the Client ID.
> >>> However, I have found that using "nms.clientId" breaks consumer
> >>> functionality for Shared Consumers, who will then receive every message
> >> in
> >>> the topic. And that, excluding the query parameter, allows Shared
> >> Consumers
> >>> to function correctly, with each consumer receiving only their share of
> >> the
> >>> messages.
> >>> Please also note that if one does not include the parameter in the Uri
> >> but
> >>> instead sets the ClientId on the connection object itself, the Shared
> >>> Customer will still not function correctly, having the same issue as
> >> using
> >>> the parameter in the Uri.
> >>> However, by not including the nms.clientId parameter, a Client ID is
> >>> automatically generated, which I guess is why it works correctly.
> >>> Nevertheless, it is less than ideal not being able to use my own Client
> >> ID.
> >>> But maybe I'm doing something wrong. Here is some simple example code
> >> using
> >>> the nms.clientId parameter that has the issue:
> >>>
> >>> static async Task SharedAsync(string clientId, CancellationToken
> >>> stoppingToken)
> >>> {
> >>> string uri =
> >>>
> >> $"amqp://localhost:61616?nms.username=artemis&nms.password=artemis&nms.clientId={clientId}";
> >>
> >> Are you giving each client the same ID or are they each being assigned
> >> there own unique client ID ?
> >>
> >>
> >>> var connecturi = new Uri(uri);
> >>> var factory = new NMSConnectionFactory(connecturi);
> >>> using IConnection connection = await
> >> factory.CreateConnectionAsync();
> >>> connection.Start();
> >>> using ISession session = await connection.CreateSessionAsync();
> >>> ITopic destination = await session.GetTopicAsync("topic-name");
> >>> using var consumer = await
> >>> session.CreateSharedConsumerAsync(destination, "sub-name");
> >>> while (!stoppingToken.IsCancellationRequested)
> >>> {
> >>> var msg = await
> >>> consumer.ReceiveAsync(TimeSpan.FromMicroseconds(250)) as ITextMessage;
> >>> if (msg is not null)
> >>> {
> >>> // process message
> >>> }
> >>> }
> >>> }
> >>>
> >>>
> >>> Thanks,
> >>> John
> >>>
> >> --
> >> Tim Bish
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [email protected]
> >> For additional commands, e-mail: [email protected]
> >> For further information, visit: https://activemq.apache.org/contact
> >>
> >>
> >>
>
> --
> Tim Bish
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> For further information, visit: https://activemq.apache.org/contact
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact