Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR causing bad request 400 seen on the server

We are having an issue with signalR. We have an auction site that runs on signalr for real time bidding. We fixed some issues with the browser and everything seemed to be working well. Then we installed new relic on our server and noticed that every minute we are getting http error code 400 on signalr connect, reconnect and abort. Here's a screenshot:

New Relic Data

SignalR connect and reconnect are the most time consuming operations of the site according to new relic.

Here is SignalR backend code (We use sql server as signalr backplane):

public class SignalRHub : Hub
{
    public void BroadCastMessage(String msg)
    {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>();

        hubContext.Clients.All.receiveMessage(msg);
    }
}

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        string appString=string.Empty;

        //Gets the connection string.
        if (System.Configuration.ConfigurationSettings.AppSettings["SignaRScaleoutConn"] != null)
        { 
            appString = System.Configuration.ConfigurationSettings.AppSettings["SignaRScaleoutConn"].ToString();
        }

        GlobalHost.DependencyResolver.UseSqlServer(appString);
        GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromMinutes(15); //I added this timeout, but it is not required.
        app.MapSignalR();
    }
}

The javascript client looks like this, it's lengthy, but most of it is jQuery to affect the DOM, I include it all in case something may be wrong inside it.

 $(function () {

            var chatProxy = $.connection.signalRHub;

            $.connection.hub.start();

            chatProxy.client.receiveMessage = function (msg) {

                var all = $(".soon").map(function () {

                    var hiddenModelId = $("#hiddenListingId");

                    if (msg == hiddenModelId.val()) {

                        $.ajax({
                            async: "true",
                            url: "/Listing/AuctionRemainingTime",
                            type: "POST",
                            dataType: 'json',
                            data: '{ "listingID": "' + msg + '"}',
                            contentType: "application/json; charset=utf-8",
                            success: function (data) {
                                if (data != null) {

                                    SoonSettings.HasReloadedThisTick = false;

                                    var element = document.getElementById(msg);

                                    var obj = JSON.parse(data)

                                    // For Clock Counter End Date Time Interval 
                                    // Adds 2 minutes to the soon clock when bid is close to finishing.
                                    var hdID = "hdn" + obj.ListingId;
                                    var hdValue = $("#" + hdID);
                                    if (obj.EndDate != hdValue.val()) {

                                        SoonSettings.HasUpdated = false; //Allows clock to change color once it gets under two minutes.

                                        $('#' + hdID).val(obj.EndDate);
                                        Soon.destroy(element);
                                        Soon.create(element, { //Recreates clock with the before 2 minute tick event.
                                            'due': 'in ' + obj.Seconds + ' seconds',
                                            'layout':'group label-uppercase',
                                            'visual':'ring cap-round progressgradient-00fff6_075fff ring-width-custom gap-0',
                                            'face':'text',
                                            'eventTick': 'tick'
                                        });
                                    }

                                    var highbid = obj.HighBidderURL;

                                    // For Date Ends Info.
                                    var ListingEndDate = $("#tdAuctionListingEndDate");

                                    if (obj.EndDate != ListingEndDate.val()) {
                                        $('#' + hdID).val(obj.EndDate);
                                        ListingEndDate.text(obj.EndDate + " Eastern");
                                        ListingEndDate.effect("pulsate", { times: 5 }, 5000);
                                    }
                                    else
                                    {
                                        $(".Bidding_Current_Price").stop(true, true); ///Removes the pulsating effect.
                                        $(".Bidding_Current_Price").removeAttr("style"); //Removes unnecessary attribute from HTML.
                                    }

                                    //Bid div notification.
                                    if (obj.AcceptedActionCount.replace(/[^:]+:*/, "") > 0) {

                                        if (obj.Disposition != '' && obj.Disposition != null) {
                                            if (obj.Disposition == "Neutral") {
                                                $("#spanNeutralBid").show();
                                                $("#divOutbidNotification").hide();
                                                $("#spanPositiveBid").hide();
                                                $("#divProxyBidNotification").hide();
                                            }
                                            else if (obj.Disposition == "Positive") {
                                                $("#spanPositiveBid").show();
                                                $("#divOutbidNotification").hide();
                                                $("#spanNeutralBid").hide();
                                                $("#divProxyBidNotification").hide();
                                            }
                                            else if (obj.Disposition == "Negative") {
                                                $("#divOutbidNotification").show();
                                                $("#spanNeutralBid").hide();
                                                $("#spanPositiveBid").hide();
                                                $("#divProxyBidNotification").hide();
                                            }
                                            else {
                                                $("#divOutbidNotification").hide();
                                                $("#spanNeutralBid").hide();
                                                $("#divProxyBidNotification").hide();
                                                $("#spanPositiveBid").hide();     
                                            }

                                        }
                                    }

                                    // For Highlight Current Price when it is Updated
                                    var hdCurrentPrice = $("#hdnCurrentPrice");

                                    if (obj.CurrentPrice != hdCurrentPrice.val()) {

                                        $(".Bidding_Current_Price").text(obj.CurrentPrice);
                                        $(".Bidding_Current_Price").effect("pulsate", { times: 5 }, 5000);
                                        $("#hdnCurrentPrice").val(obj.CurrentPrice);
                                    }
                                    else {
                                        $(".Bidding_Current_Price").stop(true, true);
                                        $(".Bidding_Current_Price").removeAttr("style");
                                    }

                                    // For ReservePrice Status
                                    $("#spanReservePriceStatus").html(obj.ReservePriceStatus);
                                    $("#smallReservePriceStatus").html(obj.ReservePriceStatus);

                                    // For Bid Count

                                    var spanBidCounter = $("#spanBidCount");

                                    $(spanBidCounter).text(obj.AcceptedActionCount);


                                    var stringAppend = "<tr id='trhHighBidder'><td><strong>HighBidder</strong></td>";
                                    stringAppend += "<td>";
                                    if (obj.isAdmin == true) {
                                        stringAppend += "<a id='anchorHighBid' href=" + obj.HighBidderURL + ">";
                                        stringAppend += "<span id='spanHighBidder'>" + obj.CurrentListingActionUserName + "</span>"
                                        stringAppend += "</a>";
                                    }
                                    else {
                                        stringAppend += "<span id='spanHighBidderAnonymous'>" + obj.CurrentListingActionUserName + "</span>";
                                    }
                                    stringAppend += "</td></tr>";

                                    if (obj.AcceptedActionCount.replace(/[^:]+:*/, "") > 0) {
                                        if ($("#tblAuctionDetail").find("#rowHighBidder").length > 0) {

                                            if ($("#tblAuctionDetail").find("#trhHighBidder").length > 0) {
                                                $("#trhHighBidder").remove();
                                            }
                                        }
                                        else {

                                            //add tr to table
                                            if (!$("#tblAuctionDetail").find("#trhHighBidder").length > 0) {
                                                $('#tblAuctionDetail > tbody > tr:eq(6)').after(stringAppend);
                                            }
                                        }
                                    }

                                    // For High Bidder

                                    if (obj.isAdmin) {

                                        var anchorElement = $("#anchorHighBid");
                                        $(anchorElement).attr("href", obj.HighBidderURL);

                                        var spanHighBidder = $("#spanHighBidder");
                                        $(spanHighBidder).text(obj.CurrentListingActionUserName);
                                    }
                                    else {
                                        var spanAdminHighBid = $("#spanHighBidderAnonymous");
                                        $(spanAdminHighBid).text(obj.CurrentListingActionUserName)
                                    }

                                }
                            },
                            error: function (xhr, textStatus, errorThrown) {

                            }
                        });
                    }
                });
            };

        });

Is there anything wrong with the client or the server signalr code that may need to be changed to avoid these errors happening so often? The 400 code has the tendency of showing up almost every minute. I am very new to signalR and know very little of how to make effective code with it.

The real time bidding in the site does work, it's just to find a way to avoid these constant errors. Any help explaining anything of how signalR works is appreciated.

Thanks,

like image 498
Carlos Jimenez Bermudez Avatar asked Apr 01 '16 16:04

Carlos Jimenez Bermudez


People also ask

How many connections SignalR can handle?

In the default mode, the app server creates five server connections with Azure SignalR Service. The app server uses the Azure SignalR Service SDK by default. In the following performance test results, server connections are increased to 15 (or more for broadcasting and sending a message to a big group).

How do I stop SignalR connection?

A SignalR connection can end in any of the following ways: If the client calls the Stop method, a stop message is sent to the server, and both client and server end the SignalR connection immediately.

Does SignalR need SSL?

If your SignalR application transmits sensitive information between the client and server, use SSL for the transport.

What is SignalR server?

SignalR is an abstraction over some of the transports that are required to do real-time work between client and server. SignalR first attempts to establish a WebSocket connection if possible. WebSocket is the optimal transport for SignalR because it has: The most efficient use of server memory.


1 Answers

I'd give a try changing the transportation method of SignalR: http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#transport and check if problem persists.

If possible to get UserAgent from Bad Request log, try to narrow down which browsers get 400 error. I think, maybe, some browsers are not connecting with correct transport method.

like image 112
TNT Avatar answered Nov 15 '22 20:11

TNT