how to send websocket message from another thread?

16 views
Skip to first unread message

William Burke

unread,
Mar 25, 2026, 7:05:57 PM (8 days ago) Mar 25
to Quarkus Development mailing list
I'm using Websocket Next.  My Websockeet is @SessionScoped.  I'm accessing a WebSocketConnection from a Multi emmiter and getting ContextNotActiveException for @SessionScoped.   I want to send a message back to the client from another thread, how do I do this?  

I'm not sure where or how to make sure the CDI context is propagated.  My Multi emitter is running on a ManagedExecutor thread

@SessionScoped
@WebSocket(path = "/_chat/routes")
public class ChatRouteEndpoint {
    static Logger log = Logger.getLogger(ChatRouteEndpoint.class);

    @Inject
    WebSocketConnection connection;  

Multi<String> multi;
multi.emitOn(Infrastructure.getDefaultExecutor())
.onItem().invoke(token -> connection.sendAndAwait(token)
                            ....;

--
Bill Burke
IBM

clement escoffier

unread,
Mar 26, 2026, 2:41:52 AM (8 days ago) Mar 26
to quark...@googlegroups.com
That's a good question.

Martin, do you know? My guess is that the connection is accessible (so you can write), but the scope is not.

Clement

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/quarkus-dev/CAL%3DE%3DjQDy_sXzCSrRndzzD_tzcm3whPTwteCMvpu_43dueKmgA%40mail.gmail.com.

Martin Kouba

unread,
Mar 26, 2026, 4:14:43 AM (8 days ago) Mar 26
to quark...@googlegroups.com, clement escoffier
Yes, so injected WebSocketConnection is a session-scoped bean. So it's
only available inside the callback methods. However, you can also
"inject" WebSocketConnection as a method param. The method argument is
not a client proxy of a CDI bean but a regular WebSocketConnection
instance that can be used anywhere. Finally, you can also list/filter
all open connections [1]; i.e. OpenConnections#findByConnectionId(). The
returned connection is not a client proxy either, so it will also work
anywhere.

HTH

Martin

[1]
https://quarkus.io/guides/websockets-next-reference#list-open-connections


On 3/26/26 07:41, clement escoffier wrote:
> That's a good question.
>
> Martin, do you know? My guess is that the connection is accessible (so
> you can write), but the scope is not.
>
> Clement
>
>> On 26 Mar 2026, at 00:05, 'William Burke' via Quarkus Development
>> mailing list <quark...@googlegroups.com> wrote:
>>
>> I'm using Websocket Next.  My Websockeet is @SessionScoped.  I'm
>> accessing a WebSocketConnection from a Multi emmiter and getting
>> ContextNotActiveException for @SessionScoped. I want to send a message
>> back to the client from another thread, how do I do this?
>>
>> I'm not sure where or how to make sure the CDI context is propagated.
>> My Multi emitter is running on a ManagedExecutor thread
>>
>> @SessionScoped
>> @WebSocket(path= "/_chat/routes")
>> publicclassChatRouteEndpoint{
>> staticLoggerlog= Logger.getLogger(ChatRouteEndpoint.class);
>>
>>     @Inject
>> WebSocketConnectionconnection;
>>
>> Multi<String> multi;
>> multi.emitOn(Infrastructure.getDefaultExecutor())
>> .onItem().invoke(token->connection.sendAndAwait(token)
>>                             ....;
>>
>> --
>> Bill Burke
>> IBM
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Quarkus Development mailing list" group.
>> To unsubscribe from this group and stop receiving emails from it, send
>> an email to quarkus-dev...@googlegroups.com <mailto:quarkus-
>> dev+uns...@googlegroups.com>.
>> To view this discussion visit https://groups.google.com/d/msgid/
>> quarkus-dev/
>> CAL%3DE%3DjQDy_sXzCSrRndzzD_tzcm3whPTwteCMvpu_43dueKmgA%40mail.gmail.com <https://groups.google.com/d/msgid/quarkus-dev/CAL%3DE%3DjQDy_sXzCSrRndzzD_tzcm3whPTwteCMvpu_43dueKmgA%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to quarkus-dev...@googlegroups.com <mailto:quarkus-
> dev+uns...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/quarkus-
> dev/A8D2900B-6121-42D7-9FD5-3DA361CB30EB%40gmail.com <https://
> groups.google.com/d/msgid/quarkus-dev/
> A8D2900B-6121-42D7-9FD5-3DA361CB30EB%40gmail.com?
> utm_medium=email&utm_source=footer>.

William Burke

unread,
Mar 26, 2026, 9:00:55 AM (8 days ago) Mar 26
to quark...@googlegroups.com, clement escoffier
I worked around it by unwrapping the proxy before going async.  I did notice (I think :-) )  that the request context was still active?  Is that the only context that gets propagated?

Will I need to write my own ThreadContextProvider for SessionScoped and just register it as a build item or META-INF/services?
Same for a custom scope?

Finally, will Mutiny and the default @Inject ManagedContext pick this propagation up automatically?

Thanks,

Bill

To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/quarkus-dev/2fa811ba-1e61-4f31-b815-c9b95ad7ee2c%40redhat.com.



--
Bill Burke
IBM

Martin Kouba

unread,
Mar 26, 2026, 9:56:19 AM (8 days ago) Mar 26
to quark...@googlegroups.com, clement escoffier
On 3/26/26 14:00, 'William Burke' via Quarkus Development mailing list
wrote:
> I worked around it by unwrapping the proxy before going async.  I did
> notice (I think :-) )  that the request context was still active?  Is
> that the only context that gets propagated?

Yes, AFAIK the request context is the only CDI context that gets propagated.

>
> Will I need to write my own ThreadContextProvider for SessionScoped and
> just register it as a build item or META-INF/services?
> Same for a custom scope?

I wouldn't do that. I would simply not use a @SessionScoped bean like
this (Multi.emitOn(Infrastructure.getDefaultExecutor()) etc.). It's a
huge mismatch IMO.

>
> Finally, will Mutiny and the default @Inject ManagedContext pick this
> propagation up automatically?

I have no idea what you're talking about. Maybe someone more skilled in
MP CP?

>
> Thanks,
>
> Bill
>
> On Thu, Mar 26, 2026 at 4:14 AM 'Martin Kouba' via Quarkus Development
> mailing list <quark...@googlegroups.com <mailto:quarkus-
> d...@googlegroups.com>> wrote:
>
> Yes, so injected WebSocketConnection is a session-scoped bean. So it's
> only available inside the callback methods. However, you can also
> "inject" WebSocketConnection as a method param. The method argument is
> not a client proxy of a CDI bean but a regular WebSocketConnection
> instance that can be used anywhere. Finally, you can also list/filter
> all open connections [1]; i.e. OpenConnections#findByConnectionId().
> The
> returned connection is not a client proxy either, so it will also work
> anywhere.
>
> HTH
>
> Martin
>
> [1]
> https://quarkus.io/guides/websockets-next-reference#list-open-
> connections <https://quarkus.io/guides/websockets-next-
> reference#list-open-connections>
>
>
> On 3/26/26 07:41, clement escoffier wrote:
> > That's a good question.
> >
> > Martin, do you know? My guess is that the connection is
> accessible (so
> > you can write), but the scope is not.
> >
> > Clement
> >
> >> On 26 Mar 2026, at 00:05, 'William Burke' via Quarkus Development
> >> mailing list <quark...@googlegroups.com <mailto:quarkus-
> <mailto:quarkus-dev%2Bunsu...@googlegroups.com> <mailto:quarkus-
> <mailto:quarkus->
> >> dev+uns...@googlegroups.com
> <mailto:dev%2Bunsu...@googlegroups.com>>.
> >> To view this discussion visit https://groups.google.com/d/msgid/
> <https://groups.google.com/d/msgid/>
> >> quarkus-dev/
> >>
> CAL%3DE%3DjQDy_sXzCSrRndzzD_tzcm3whPTwteCMvpu_43dueKmgA%40mail.gmail.com <http://40mail.gmail.com> <https://groups.google.com/d/msgid/quarkus-dev/CAL%3DE%3DjQDy_sXzCSrRndzzD_tzcm3whPTwteCMvpu_43dueKmgA%40mail.gmail.com?utm_medium=email&utm_source=footer <https://groups.google.com/d/msgid/quarkus-dev/CAL%3DE%3DjQDy_sXzCSrRndzzD_tzcm3whPTwteCMvpu_43dueKmgA%40mail.gmail.com?utm_medium=email&utm_source=footer>>.
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Quarkus Development mailing list" group.
> > To unsubscribe from this group and stop receiving emails from it,
> send
> > an email to quarkus-dev...@googlegroups.com
> <mailto:quarkus-dev%2Bunsu...@googlegroups.com> <mailto:quarkus-
> <mailto:quarkus->
> > dev+uns...@googlegroups.com
> <mailto:dev%2Bunsu...@googlegroups.com>>.
> > To view this discussion visit https://groups.google.com/d/msgid/
> quarkus- <https://groups.google.com/d/msgid/quarkus->
> > dev/A8D2900B-6121-42D7-9FD5-3DA361CB30EB%40gmail.com
> <http://40gmail.com> <https://
> > groups.google.com/d/msgid/quarkus-dev/ <http://groups.google.com/
> d/msgid/quarkus-dev/>
> > A8D2900B-6121-42D7-9FD5-3DA361CB30EB%40gmail.com
> <http://40gmail.com>?
> > utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to quarkus-dev...@googlegroups.com
> <mailto:quarkus-dev%2Bunsu...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/
> quarkus-dev/2fa811ba-1e61-4f31-b815-c9b95ad7ee2c%40redhat.com
> <https://groups.google.com/d/msgid/quarkus-dev/2fa811ba-1e61-4f31-
> b815-c9b95ad7ee2c%40redhat.com>.
>
>
>
> --
> Bill Burke
> IBM
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to quarkus-dev...@googlegroups.com <mailto:quarkus-
> dev+uns...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/quarkus-
> dev/CAL%3DE%3DjSAZgwvEVunbRxqMEG7MZcJFcY%2BBNBdwG650eKiG-
> jGHA%40mail.gmail.com <https://groups.google.com/d/msgid/quarkus-dev/
> CAL%3DE%3DjSAZgwvEVunbRxqMEG7MZcJFcY%2BBNBdwG650eKiG-
> jGHA%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Stephane Epardaud

unread,
Mar 26, 2026, 11:51:25 AM (8 days ago) Mar 26
to quark...@googlegroups.com
On Thu, 26 Mar 2026 at 14:56, 'Martin Kouba' via Quarkus Development mailing list <quark...@googlegroups.com> wrote:
> Will I need to write my own ThreadContextProvider for SessionScoped and
> just register it as a build item or META-INF/services?
> Same for a custom scope?

I wouldn't do that. I would simply not use a @SessionScoped bean like
this (Multi.emitOn(Infrastructure.getDefaultExecutor()) etc.). It's a
huge mismatch IMO.

Well… I don't think it's that obvious that a request scope should be propagated but not a session scope. Unless the session scope in question has a different meaning than the standard session definition. It seems to me that if the request scope feels OK to propagate, then the session (which spans multiple requests) also belongs there.
 
> Finally, will Mutiny and the default @Inject ManagedContext pick this
> propagation up automatically?

Yes. If you declare your `ThreadContextProvider` for the session scope, Mutiny will automatically include it for propagation. And then you move from your current propagation issues (the lack thereof being the most prominent one) to the wonderful world of the other propagation issues 🥳

Ladislav Thon

unread,
Mar 26, 2026, 12:02:15 PM (8 days ago) Mar 26
to quark...@googlegroups.com
 
Yes. If you declare your `ThreadContextProvider` for the session scope, Mutiny will automatically include it for propagation. And then you move from your current propagation issues (the lack thereof being the most prominent one) to the wonderful world of the other propagation issues 🥳

Without responding to the rest of this thread, I would like to highlight that our Mutiny + context propagation integration is wrong, because it captures contexts at the time the `Uni`/`Multi` is created, which may very well happen (and relatively often does happen) outside of the actual request handler. Naively, contexts should be captured at the moment the `Uni`/`Multi` is subscribed to, but that typically happens in a framework, so again outside of the actual request handler. I might have some ideas for other context propagation issues, but for this one, I don't even have an idea.

LT
 

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/quarkus-dev/CAKU9E9uFPU%2BjvojgU7LBo2fqnkz%3DHH04HZELhk3MXYaNQXG9ag%40mail.gmail.com.

Stephane Epardaud

unread,
Mar 26, 2026, 12:08:26 PM (8 days ago) Mar 26
to quark...@googlegroups.com
On Thu, 26 Mar 2026 at 17:02, Ladislav Thon <lad...@gmail.com> wrote:
Without responding to the rest of this thread, I would like to highlight that our Mutiny + context propagation integration is wrong, because it captures contexts at the time the `Uni`/`Multi` is created, which may very well happen (and relatively often does happen) outside of the actual request handler. Naively, contexts should be captured at the moment the `Uni`/`Multi` is subscribed to, but that typically happens in a framework, so again outside of the actual request handler. I might have some ideas for other context propagation issues, but for this one, I don't even have an idea.

I disagree with this. It was meant to capture the context that is in the lexical scope of the lambda that captures it, precisely like lambdas capture variables from their lexical scopes, which is what is intuitive, and happens to be correct in both the request and session context cases.

Now, it is incorrect in the case of at least tracing, which changes contexts in ways that are not lexical, and probably other types of contexts. But I don't think that's a problem here for these contexts. 


William Burke

unread,
Mar 26, 2026, 2:16:47 PM (8 days ago) Mar 26
to quark...@googlegroups.com
On Thu, Mar 26, 2026 at 11:51 AM Stephane Epardaud <stephane...@gmail.com> wrote:


On Thu, 26 Mar 2026 at 14:56, 'Martin Kouba' via Quarkus Development mailing list <quark...@googlegroups.com> wrote:
> Will I need to write my own ThreadContextProvider for SessionScoped and
> just register it as a build item or META-INF/services?
> Same for a custom scope?

I wouldn't do that. I would simply not use a @SessionScoped bean like
this (Multi.emitOn(Infrastructure.getDefaultExecutor()) etc.). It's a
huge mismatch IMO.

Well… I don't think it's that obvious that a request scope should be propagated but not a session scope. Unless the session scope in question has a different meaning than the standard session definition. It seems to me that if the request scope feels OK to propagate, then the session (which spans multiple requests) also belongs there.


Consider LC4j with @Tools that  run in parallel.  Makes perfect sense to have access to the CDI scopes of the caller because it is all one operation and you may want to share information.

 
 
> Finally, will Mutiny and the default @Inject ManagedContext pick this
> propagation up automatically?

Yes. If you declare your `ThreadContextProvider` for the session scope, Mutiny will automatically include it for propagation. And then you move from your current propagation issues (the lack thereof being the most prominent one) to the wonderful world of the other propagation issues 🥳

ManagedExecutions should pick it up propagation too?   Guess I'll just try it.

One thing that bothers me is the calling thread.  How should the calling thread handle CDI context deactivation/termination?  Like this?

try {
    multiOrUni.onTermination().invoke(() -> requestContext.terminate());
} finally {
   requestContext.deactivate();
}

Ty

 

--
Bill Burke
IBM

Stephane Epardaud

unread,
Mar 27, 2026, 6:06:47 AM (7 days ago) Mar 27
to quark...@googlegroups.com
On Thu, 26 Mar 2026 at 19:16, 'William Burke' via Quarkus Development mailing list <quark...@googlegroups.com> wrote:
Consider LC4j with @Tools that  run in parallel.  Makes perfect sense to have access to the CDI scopes of the caller because it is all one operation and you may want to share information.

Well, the issue here is that the CDI scopes in question (session, request) have not been designed to support parallel execution. So… it might not work like you expect it to 😬
 
ManagedExecutions should pick it up propagation too?   Guess I'll just try it.

Yes, that's its only purpose.
 
One thing that bothers me is the calling thread.  How should the calling thread handle CDI context deactivation/termination?  Like this?

try {
    multiOrUni.onTermination().invoke(() -> requestContext.terminate());
} finally {
   requestContext.deactivate();
}

Like for the ThreadContextProvider for request context: you activate the context before the scoped method, deactivate it after, and terminate it on the end of the uni/multi. And pray that that uni/multi is not outlived by any thread you started which requires it. If it waits for them all to be done before being terminated, it should be fine.

Martin Kouba

unread,
Mar 27, 2026, 6:11:38 AM (7 days ago) Mar 27
to quark...@googlegroups.com, Stephane Epardaud
On 3/27/26 11:06, Stephane Epardaud wrote:
>
>
> On Thu, 26 Mar 2026 at 19:16, 'William Burke' via Quarkus Development
> mailing list <quark...@googlegroups.com <mailto:quarkus-
> d...@googlegroups.com>> wrote:
>
> Consider LC4j with @Tools that  run in parallel.  Makes perfect
> sense to have access to the CDI scopes of the caller because it is
> all one operation and you may want to share information.
>
>
> Well, the issue here is that the CDI scopes in question (session,
> request) have not been designed to support parallel execution. So… it
> might not work like you expect it to 😬

In fact, this is not true for session scoped beans. These were typically
subject of parallel processing (e.g. HTTP session -> multiple HTTP
requests).

>
> ManagedExecutions should pick it up propagation too?   Guess I'll
> just try it.
>
>
> Yes, that's its only purpose.
>
> One thing that bothers me is the calling thread.  How should the
> calling thread handle CDI context deactivation/termination?  Like this?
>
> try {
>     multiOrUni.onTermination().invoke(() ->
> requestContext.terminate());
> } finally {
>    requestContext.deactivate();
> }
>
>
> Like for the ThreadContextProvider for request context: you activate the
> context before the scoped method, deactivate it after, and terminate it
> on the end of the uni/multi. And pray that that uni/multi is not
> outlived by any thread you started which requires it. If it waits for
> them all to be done before being terminated, it should be fine.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to quarkus-dev...@googlegroups.com <mailto:quarkus-
> dev+uns...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/quarkus-
> dev/CAKU9E9stBwOJ5_ph9Raqwqc0j0knJEiUO20iZpLxitnJ-
> q%3DKPA%40mail.gmail.com <https://groups.google.com/d/msgid/quarkus-dev/
> CAKU9E9stBwOJ5_ph9Raqwqc0j0knJEiUO20iZpLxitnJ-q%3DKPA%40mail.gmail.com?
> utm_medium=email&utm_source=footer>.

Stephane Epardaud

unread,
Mar 27, 2026, 6:19:04 AM (7 days ago) Mar 27
to quark...@googlegroups.com
On Fri, 27 Mar 2026 at 11:11, Martin Kouba <mko...@redhat.com> wrote:
In fact, this is not true for session scoped beans. These were typically
subject of parallel processing (e.g. HTTP session -> multiple HTTP
requests).

Oh, you're right, this is pretty obvious now that you point it out. Great :) 
Reply all
Reply to author
Forward
0 new messages