Usage of SignalR and javascript in Acumatica

Hi everybody,

 

 

today I want to describe how you can use SignalR and javascript in Acumatica. I will describe following functionality:

1. User 1 opens sales order SO006768

2. User 2 opens sales order SO006768

3. User 1 modifies Sales order, and clicks on Save button

4. User 2 gets following notification:

One of the ways to achieve that, is to use SignalR and a bit of jQuery.

In order to achieve that, following steps are needed:

1. Create interface, which will be a backbone of functionality:

public interface ISalesOrderNotify
{
    Task<stringOrderWasChanged(string refNbr);
}

 2. Create class, which will bound interface implementation to SignalR of Acumatica:

public class SOOrderHub : Hub<ISalesOrderNotify>
{
    public async Task<stringNotify(string refNbr)
    {
        await Clients.Others.OrderWasChanged(refNbr);
        return await Clients.Caller.OrderWasChanged(refNbr);
    }
}

 What I want to specifically highlight, is inheritance from the class Hub, which bounds SignalR with Interface and particular implementation.

3. Inform Acumatica framework about such connection:

public class ServiceRegistration : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<SOOrderHub>().ExternallyOwned();
    }
}

4. And finally, explain in graph or graph extension, how steps 1 - 3 will be used:

public class SOOrderentryExt : PXGraphExtension<SOOrderEntry>
{
    public static bool IsActive() => true;
 
    [InjectDependency]
    internal IConnectionManager SignalRConnectionManager { getset; }
 
    public override void Initialize()
    {
        base.Initialize();
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<SOOrderHub>();
 
    }
 
    [PXOverride]
    public void Persist(Action basePersist)
    {
        basePersist();
        var currentOrder = Base.CurrentDocument.Current.RefNbr;
 
        var cnt = SignalRConnectionManager.GetHubContext<SOOrderHub>();
        cnt.Clients.All.OrderWasChanged(currentOrder);
    }
}
5. In your aspx.cs mention, that you want to have SignalR and jquery:
protected void Page_Init(object sender, EventArgs e)
	{
		Master.PopupWidth = 950;
		Master.PopupHeight = 600;
        // panel = (PXFormView)this.PanelAddSiteStatus.FindControl("formSitesStatus");
 
        this.ClientScript.RegisterClientScriptInclude(this.GetType(), "jq", VirtualPathUtility.ToAbsolute("~/Scripts/jquery-3.1.1.min.js"));
        this.ClientScript.RegisterClientScriptInclude(this.GetType(), "jqsr", VirtualPathUtility.ToAbsolute("~/Scripts/jquery.signalR-2.2.1.min.js"));
        this.ClientScript.RegisterClientScriptInclude(this.GetType(), "hb", VirtualPathUtility.ToAbsolute("~/signalr/hubs"));
    }
6. In your aspx describe a bit of javascript logic:
<script type="text/javascript">
    var hubProxy = $.connection.sOOrderHub;
    hubProxy.connection.start()
        .done(function () {
                console.log("hub proxy started");
            }
        );
    hubProxy.on(
        "OrderWasChanged", function(refNbr) {
            var value = $("#ctl00_phF_form_t0_edOrderNbr_text").val();
            if (value === refNbr) {
                alert("Sales Order:" + refNbr + " was modified");
            }
        }
    );
</script>
Summary

With usage of such technique, you'll be able to connect your C# part to js in a bit more invisible way, and add a bit more interactivity. Couple of additional details I'll add later on my youtube video.

 

 

 

 

 

Add comment

Loading