Skip to content

Is there anyway to send a message from a service worker? #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dodyg opened this issue Oct 3, 2023 · 8 comments
Closed

Is there anyway to send a message from a service worker? #17

dodyg opened this issue Oct 3, 2023 · 8 comments

Comments

@dodyg
Copy link

dodyg commented Oct 3, 2023

It's not very clear from this whether it is possible to send a message from IMathService.

image

According to this PostEvent is only available via the worker itself.
image

@LostBeard
Copy link
Owner

According to this PostEvent is only available via the worker itself.

I'm not sure where the misunderstanding lies here. Hopefully this clears it up.

Option 1

In your window context

var worker = await workerService.GetWebWorker();
worker.OnMessage += (sender, msg) =>
{
    // use msg.TargetName to get the message identifier used as the first parameter in ```SendEventToParents```
    if (msg.TargetName == "progress")
    {
        PiProgress msgData = msg.GetData<PiProgress>();
        piProgress = msgData.Progress;
        StateHasChanged();
    }
};

In your WebWorker context to send a message to the window that is listening

workerService.SendEventToParents("progress", new PiProgress { Progress = piProgress });

That code shows how a window can listen to messages from the worker and how to send messages to the window listening for those messages.

Option 2 (WebWorker only, not available in SharedWebWorker)

Another option is to use WebWorkerService.DedicatedWorkerParent from inside a WebWorker.

WebWorkerService.DedicatedWorkerParent is equivalent to WebWorkerService.GetWebWorker except the returned value points to the Window context that created the WebWorker instead of a new WebWorker.

From inside a WebWorker context, to get an interface that allows calling a Service on the Window context from a WebWorker context just like a Window can do with a WebWorker.

// get a handle to the service interface ISomeWindowService in the Window context
var someWindowService = WebWorkerService.DedicatedWorkerParent.GetService<ISomeWindowService>(); 
// call a method on the window context
await someWindowService.SomeMethod();

Hopefully that helps. If you see a way to make the documentation more understandable please let me know. Thank you.

@dodyg
Copy link
Author

dodyg commented Oct 3, 2023

public interface ISomeWindowService 
{
   Task DoSomethingAsync();
}

public class SomeWindowService: ISomeWindowService
{
   public async Task DoSomethingAsync()
   {
       //is there any mechanism that allows me to post a message from inside this method?     
   }
}

@LostBeard
Copy link
Owner

LostBeard commented Oct 3, 2023

The window that created the WebWorker should already have a handle to the WebWorker but you can get the caller using a special parameter.

@LostBeard
Copy link
Owner

LostBeard commented Oct 3, 2023

public interface ISomeWindowService 
{
   Task DoSomethingAsync(ServiceCallDispatcher caller);
}

public class SomeWindowService: ISomeWindowService
{
   public async Task DoSomethingAsync(ServiceCallDispatcher caller)
   {
        // caller will be the WebWorker context that called the method. 
        // it must be named caller and be of type ServiceCallDispatcher but it can be the first, last, or even middle parameter
        // the dispatcher auto inserts it when the method is called
        // when calling DoSomethingAsync you would call it with a null in the caller parameter place. Ex. DoSomethingAsync(null)

        // send message to OnMessage event handler of the caller (requires it is listening for it)
        // web workers can attach a listener via WebWorkerService.DedicatedWorkerParent.OnMessage
        // window can attach a listener after the worker is created via worker.OnMessage
        caller.SendEvent("someevent", someEventData);

        // OR
        // using a service to call method on the caller context
        var callerService = caller.GetService<ISomeServiceOnTheCaller>();
        await callerService.SomeMethodInCallerContext();
   }
}

@LostBeard
Copy link
Owner

That mechanism works in a WebWorker, SharedWebWorker, and Window contexts to get the caller context.

@dodyg
Copy link
Author

dodyg commented Oct 3, 2023

dodyg/practical-aspnetcore#377

@dodyg
Copy link
Author

dodyg commented Oct 3, 2023

Thank you so much for your help. This is a brilliant library.

@dodyg dodyg closed this as completed Oct 3, 2023
@LostBeard
Copy link
Owner

Thank you and glad to help. I will continue to work on improving the documentation. Some of these advanced features haven't quite made it into the docs yet but should be there soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants