使用 SignalR、WCF 双工服务和 ASP.Net 通用处理程序向客户端推送通知?

Posted

技术标签:

【中文标题】使用 SignalR、WCF 双工服务和 ASP.Net 通用处理程序向客户端推送通知?【英文标题】:Push notifications to client with SignalR,WCF duplex service and ASP.Net generic handler? 【发布时间】:2015-10-10 10:03:56 【问题描述】:

我应该使用开发的 WCF 双工服务将文件发送到指定的 IP 地址, 所以我有一些回调操作,它们应该用作客户端的通知,我得出这个结论是使用 SignalR,但我是 SignalR 的新手,因为这个原因实际上并不知道 SignalR 是否适合这样做.

让我们看看我正在处理哪些代码,在 ASP.Net 通用处理程序中我的“SendToServer”操作并使用 WCF 客户端代理如下:

SendClient sendClient = new SendClient(new SendCallback(),new System.ServiceModel.NetTcpBinding(),new System.ServiceModel.EndpointAddress(endPointAddress)); 
        sendClient.OperationFailed += sendClient_OperationFailed;
        sendClient.OperationTimedOut += sendClient_OperationTimedOut;
        sendClient.SendingFinished += sendClient_SendingFinished;
        sendClient.ConnectionClosed += sendClient_ConnectionClosed;
        sendClient.ConnectionRefused += sendClient_ConnectionRefused;
        sendClient.InstanceStored += sendClient_InstanceStored;
sendClient.Send(/*Array of resources ids*/,  /*Server instance*/);

我的事件处理程序如下:

public void sendClient_InstanceStored(object sender, int currentInstance, int totalInstance, int currentStudy, int TotalStudy)
     
        //Get fired when one file successfully sent
     
    public void sendClient_ConnectionRefused(object sender, EventArgs e)
    
        //Connection refused
    

    public void sendClient_ConnectionClosed(object sender, EventArgs e)
    
        //Connection closed
    

    public void sendClient_SendingFinished(object sender, EventArgs e)
    
        //Sending finished
    

    public void sendClient_OperationTimedOut(object sender, EventArgs e)
    
        //Operation timed out
    

    public void sendClient_OperationFailed(object sender, EventArgs e)
    
        //Operation failed
    

在JS中调用这个动作如下:

 $.ajax(
            cache: false,
            type: "POST",
            url: '../Handlers/Study/Send.ashx',
            dataType: "json",
            data: 
                Action: "SendToServer",
                Hostname: DeviceHostname, Port: DevicePort, Description: Description, Ids2Send: JSON.stringify(rows)
            ,
            async: true,
            success: function (data) 
                if (data.Success == false) 
                    $("#loader-Send").remove();
                    $(".ui-dialog-buttonpane button:contains('Send')").button("enable");
                    showNoticeMessage("Can not send to Server!");
                    return;
                
            ,
            error: function (x, e) 
                $("#loader-Send").remove();
                $(".ui-dialog-buttonpane button:contains('Send')").button("enable");
                showNoticeMessage("Can not send to Server!");
            
        );

是否可以在启动$.ajax 后在客户端使用该事件处理程序作为 SignalR 的通知?

还有其他方法可以在不使用 SignalR 的情况下执行此操作吗?

提前致谢。

【问题讨论】:

【参考方案1】:

如果有人需要这里是解决方案:

1-应该安装SignalR

2- 创建一个Owin 启动类,例如:

   public class Startup

    public void Configuration(IAppBuilder app)
    
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
        app.MapSignalR();
    

3- 定义和实现您自己的通知类,例如:

[HubName("sendNotifier")]
public class SendNotifier : Hub

    public string CurrentConnectionID  get; set; 
    public void SendStarted()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).sendStarted();
    
    public void SendFailed()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).sendFailed();
    
    public void InstanceStored(int currentInstance, int totalInstance, int currentStudy, int totalStudy)
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).instanceStored(currentInstance, totalInstance, currentStudy, totalStudy);
    
    public void SendFinished()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).sendFinished();
    
    public void ConnectionClosed()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionClosed();
    
    public void ConnectionTimedOut()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionTimedOut();
    
    public void ConnectionRefused()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionRefused();
    

    public void ConnectionFailed()
    
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionFailed();
    

4- 例如,在事件处理程序中,我们可以调用通知方法

 public void sendClient_ConnectionEstablished(object sender, EventArgs e)
    
        SendNotifier sendNotifier = new SendNotifier();
        sendNotifier.CurrentConnectionID = ClientID;
        sendNotifier.SendStarted();
    

注意:我在 Ajax 请求中传递了 ClientID

和客户端代码:

 var hub = $.connection.sendNotifier;
    hub.client.sendStarted = function () 

    ;

    hub.client.sendFinished = function () 
    ;

    hub.client.sendFailed = function () 
    ;
    //var temp;
    hub.client.instanceStored = function (currentInstance, totalInstance, currentStudy, totalStudy) 
    ;

    hub.client.connectionClosed = function () 
    ;

    hub.client.connectionTimedOut = function () 
    ;

    hub.client.connectionRefused = function () 
    ;

    hub.client.connectionFailed = function () 
    ;

    $.connection.hub.logging = true;
    $.connection.hub.start().done(function () 
    );

还有ClientIDClientID: $.connection.hub.id

SignalR 和它的东西应该在页面头部引用。

【讨论】:

以上是关于使用 SignalR、WCF 双工服务和 ASP.Net 通用处理程序向客户端推送通知?的主要内容,如果未能解决你的问题,请参考以下文章

SignalR 自托管与 WCF 服务和客户端将是桌面用户

WCF SOAP

WCF 服务中的 SignalR 用于更新网站客户端

WCF 双工服务和 TCP 端口耗尽

如何在 azure wcf 中继中处理双工 wcf

WCF(Silverlight)双工 - 不打服务器