0

I use SignalR to print a document from a web site through a printer connected to the network. When I test it on a pc, it works fine. The problem is when there is more than one pc connected, since it prints as many copies as the number of computers connected using SignalR.

This is the html code:

$(document).ready(function () {  
var myHub = $.connection.myHub;
        var direccionWeb = $("#direccionWeb").val().toString();
        $.connection.hub.url = direccionWeb + "/signalr";
        $.connection.hub.start().done(function () {
            myHub.server.broadcastMessageToPrinterReportTicket(global_venta, global_mesa, nombregarzon, idgrupo, grupo);

        }).fail(function (error) {
            console.error(error);
        });
 });

This is the HUB file:

public void BroadcastMessageToPrinterReportTicket(String global_venta, String global_mesa, String nombregarzon, String idgrupo, String grupo)
    {
        string nombreImpresora = grupo;
        //resto de código para obtener datos.......

        String nombreRDLC = "report_ticket.rdlc";
        String nombreDataSet = "DataSet_ticket";

        Clients.All.imprimeReport(nombreImpresora, parametros, dt, nombreRDLC, nombreDataSet);

    }

This is the windows form:

public partial class Form1 : Form
{
    HubConnection hubConnection;
    IHubProxy hubProxy;
    //Install-Package HtmlRenderer.PdfSharp -Version 1.5.0.6
    public Form1()
    {
            InitializeComponent();
            IncializaSignalR();
            hubConnection.Closed += IncializaSignalR;
            hubConnection.Start().Wait();
        }

     private void IncializaSignalR()
    {

        String direccionServer = "https://mipaginaweb.cl";

        hubConnection = new HubConnection(direccionServer + "/signalr/hubs");
        hubProxy = hubConnection.CreateHubProxy("MyHub");
        CheckForIllegalCrossThreadCalls = false;


        hubProxy.On<String, ReportParameter[], DataTable, String, String>("imprimeReport", (nombreImpresora, parametros, dt, nombreRDLC, nombreDataSet) =>
        {
            //Instrucción de código para imprimir con reportviewer
          }
        });
   }

When checking the code, I suspect that the cause of the problem could be the "All" statement:

  Clients.All.imprimeReport(.......

Because apparently, it sends the request to all connected users. However, the instruction should go only from the client's PC who made the request to print, as intended.

DavidM
  • 307
  • 2
  • 6
  • 22

1 Answers1

0

When a client connects, they are given a unique "Connection ID" that is stored on the Context object (accessible in the Hub class's method that is handling the call).

You can then use this ID to send them messages, ie:

Clients(Context.ConnectionId).SomeClientMethod();

Sounds like that's what you need to do. Note that because the connection ID is part of a request, if you need it later you will need to store it off in memory somewhere along with a key for the device or generated action so you can fetch it appropriately.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Do you have an example? I tried this: `Clients.User(Context.ConnectionId).imprimeReport(nombreImpresora, parametros, dt, nombreRDLC, nombreDataSet);` but it doesn't call the print function – DavidM Jan 03 '18 at 16:43
  • @DavidM Its not Clients.User, just Clients. Based on your comment in the actual question; it sounds like the client may not be maintaining the connection? – BradleyDotNET Jan 03 '18 at 17:06
  • @BradleyDotNET, Should we change the hubProxy.On("imprimeReport", (nombreImpresora, parametros, dt, nombreRDLC, nombreDataSet) => { // } For another instruction? – Danilo Jan 03 '18 at 17:08
  • @Danilo That looks right to me. Is that object being disposed somewhere? Obviously it worked at some point because your Clients.All worked – BradleyDotNET Jan 03 '18 at 17:14
  • I found this solution: (https://stackoverflow.com/questions/19522103/signalr-sending-a-message-to-a-specific-user-using-iuseridprovider-new-2-0) but I want to know how to get the user ID and send it to the client – DavidM Jan 03 '18 at 17:16
  • I see that when using Clients.All.imprimeReport (....) it works fine, but when it changes to another method, on the client side it does not pass the function's breakpoint.imprimeReport (So they tell me) – Danilo Jan 03 '18 at 17:22
  • @DavidM I haven't done ASP.NET authentication; so I can't help you there. Going direct with Caller (assuming you never left the request of course) or the connection ID never fails for me. The primary issue is if you try to use one of those outside an actual request context (which is quite common) which is why I mention you may need to store it off – BradleyDotNET Jan 03 '18 at 17:25