`

史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例

阅读更多

1、概述

通过前面几篇文章

史上最全面的SignalR系列教程-1、认识SignalR

史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式

史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式

我们对SignalR的概念以及SignalR的最主要的两类通信模型(Persistent Connections与Hubs)进行了详细的对比讲解,也做了案例展示。本篇将为大家介绍.NET特有的Self-Host自托管的应用,即以Self-Host自托管为宿主加载SignalR服务。

宿主一词我们不会陌生,它可以看作是一个基础设施,它为一些服务和功能提供最底层的支持,如你的web应用程序可以运行在iis或者apache上,而这两个东西就是web应用程序的宿主,而今天说的自主宿主SelfHost它可以自己去监听自己的服务,如你可以把一个web应用程序宿主到一个console控制台程序上,或者把一个webApi宿主到一个console或者windowService上,这都是可以的。

Self-Host的介绍我们可以参考msdn官方事例https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/self-host 这是一个wcf的事例。

SignalR常常依托于ASP.NET应用程序运行于IIS中,但它还可以自我托管(比如作为console winform、Windows service),只要我们使用self-host库就可以了。该库向所有的SignalR 2库一样,构建于OWIN (Open Web Interface for .NET)。OWIN定义了一个在.NET web 服务端和web 应用程序的抽象。OWIN解耦了从服务端来的web 应用程序,这使得OWIN对于子托管web应用程序于自己的进程中得以表现得很完美。

有的小伙伴可能就要问了,为什么一定要使用这种方式来托管呢?基于IIS的方式不是更简单吗?不托管于IIS的原因主要有以下方面的考虑:

  • 我们已经构建了一个服务端程序,没有运行在IIS上,重新搭建成本太高。
  • IIS的方式性能开销很大。
  • signalR需要扩展到现有程序中,如Windows服务中等。
  • 其他的一些原因....

本篇主要讲解以下内容:

  1. 使用Self-Host方式创建SignalR服务端
  2. 用javascript客户端访问SignalR Self-Host服务端
  3. 用WinForm客户端接收SignalR Self-Host服务端消息

2、使用Self-Host方式创建SignalR服务端

为了更简单的说明self-host托管的方式,我们用控制台应用程序来做演示。当然我们也可以自托管到Windows服务中去,如果你更希望托管到Windows服务,可以参考Self-Hosting SignalR in a Windows Service

在上一项目的基础上,我们新建一个名为:SignalRSelfHost的控制台应用程序,如下所所示:

新建SignalRSelfHost控制台应用程序

要使用Selft-Host宿主SignalR,必须引用Microsoft.AspNet.SignalR.SelfHost包。我们在程序包管理控制台输入以下命令安装SelfHost包。

Install-Package Microsoft.AspNet.SignalR.SelfHost

要想支持跨域访问,还需要安装

Install-Package Microsoft.Owin.Cors

如果用命令的方式安装失败,我们可以用NuGet的方式安装,如下图所示。

NuGet方式安装Self-Host

NuGet方式安装Self-Host

编写代码如下:

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;

namespace SignalRSelfHost
{
    class Program
    {
        static void Main(string[] args)
        {
            // This will *ONLY* bind to localhost, if you want to bind to all addresses
            // use http://*:8080 to bind to all addresses. 
            // See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx 
            // for more information.
            string url = "http://localhost:8077";
            using (WebApp.Start(url))
            {
                Console.WriteLine("SignalR Server running on {0}", url);
                Console.ReadLine();
            }
        }
    }

    /// <summary>
    /// 该类含有SignalR服务端的配置(该教程使用的唯一的配置是用来调用UseCors), 
    /// MapSignalR为所有形式的Hub对象创建了路由规则
    /// </summary>
    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }

    /// <summary>
    /// SignalR的Hub 类是程序要提供给客户端的
    /// 该类就一个方法,Send:客户端可以用来发送消息给其他客户端
    /// </summary>
    public class MyHub : Hub
    {
        //服务端的方法,客户端可以去调用
        public void Send(string name, string message)
        {
            //调用客户端的方法addMessage(string s1,string s2);      
            Clients.All.addMessage(name, message);
        }
    }
}

代码说明:

  • Program:包含程序的主方法。在这个方法中,类型为Startup的web应用程序启动于指定的URL (http://localhost:8077)。 如果需要更加安全一点,可以支持SSL,请去这里看看How to: Configure a Port with an SSL Certificate

  • Startup: 该类含有SignalR服务端的配置(该教程使用的唯一的配置是用来调用UseCors), MapSignalR为所有形式的Hub对象创建了路由规则。

  • MyHub:SignalR的Hub 类是程序要提供给客户端的。 该类就一个方法:Send, 客户端可以用来发送消息给其他客户端。

编译运行SignalR控制台服务端如下。

SignalR控制台服务端启动

可以看到我们的控制台服务端已经成功启动起来了。

3、用javascript客户端访问SignalR Self-Host服务端

3.1、新建SignalRSelfHostJSClient的MVC空项目

新建SignalRSelfHostJSClient的MVC空项目

3.2、添加Microsoft.AspNet.SignalR.JS的引用

添加Microsoft.AspNet.SignalR.JS的引用

3.3、新建Default.html页面

代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>SignalRSelfHostJSClient Chat</title>
    <style type="text/css">
        .container {
            background-color: #a1c6ec;
            border: thick solid #e62fc7;
            padding: 20px;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <input type="text" id="message" style="width:350px;" placeholder="请输入消息内容..."/>
        <input type="button" id="sendmessage" value="发送" />
        <input type="hidden" id="displayname" />
        <ul id="discussion"></ul>
    </div>
    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-1.6.4.min.js"></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.4.1.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="http://localhost:8077/signalr/hubs"></script>
    <!--Add script to update the page and send messages.-->
    <script type="text/javascript">
        $(function () {
            //Set the hubs URL for the connection
            $.connection.hub.url = "http://localhost:8077/signalr";
            // Declare a proxy to reference the hub.
            var chat = $.connection.myHub;

            // Create a function that the hub can call to broadcast messages.
            chat.client.addMessage = function (name, message) {
                // Html encode display name and message.
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page.
                $('#discussion').prepend('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box.
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // Call the Send method on the hub.
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });
            });
        });
    </script>
</body>
</html>

3.4、运行效果

先运行SignalRSelfHost控制台服务端后,再运行两个我们的测试客户端,分别输入不同的用户名,试试聊天的效果,如下图所示。

SignalRSelfHostJSClient运行效果

4、用WinForm客户端接收SignalR Self-Host服务端消息

4.1、新建SignalRSelfHost的WinForm项目

新建SignalRSelfHost的WinForm项目

4.2、使用NuGet安装Microsoft.AspNet.SignalR.Client包

NuGet安装Microsoft.AspNet.SignalR.Client包

4.3、制作测试界面如下:

SignalRWinForm测试客户端设计界面

编写界面代码如下:

using Microsoft.AspNet.SignalR.Client;
using System;
using System.Configuration;
using System.Windows.Forms;

namespace SignalRSelfHostWinFormClient
{
    /// <summary>
    /// SignalRSelfHost WinForm测试客户端
    /// 用于接收消息(需配合SignalRSelfHostJSClient项目使用)
    /// </summary>
    public partial class SignalRSelfHostWinFormClientTest : Form
    {
        //定义代理,广播服务连接相关
        private static IHubProxy HubProxy { get; set; }
        private static readonly string ServerUrl = ConfigurationManager.AppSettings["SignalRServer"];
        //定义一个连接对象
        public static HubConnection Connection { get; set; }

        public SignalRSelfHostWinFormClientTest()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
        }

        private void SignalRSelfHostWinFormClientTest_Load(object sender, EventArgs e)
        {
            Connection = new HubConnection(ServerUrl);            
            Connection.Closed += Connection_Closed;
            HubProxy = Connection.CreateHubProxy("MyHub");
            HubProxy.On<string, string>("addMessage", RecvMsg);//接收实时信息
            Connection.Start().ContinueWith(task =>
            {
                if (!task.IsFaulted)
                {
                    msgContent.AppendText(string.Format("与Signal服务器连接成功,服务器地址:{0}\r\n",ServerUrl));
                }
                else
                {
                    msgContent.AppendText("与服务器连接失败,请确认服务器是否开启。\r\n");
                }
            }).Wait();
        }

        private void Connection_Closed()
        {
            msgContent.AppendText("连接关闭...\r\n");
        }

        private void RecvMsg(string name, string message)
        {
            msgContent.AppendText(string.Format("接收时间:{0},发送人:{1},消息内容:{2},\r\n", DateTime.Now, name, message));          
        }
    }
}

4.4、运行效果:

SignalRWinForm测试客户端运行效果

通过以上的详细讲解,我们已经非常清楚的了解了如何通过SignalR打通各终端以实现相互沟通的通信。例子虽然比较简洁,但完全可以以此为基础,扩展更复杂的业务应用。

5、代码下载

实例源码可以移步github下载,地址:https://github.com/yonghu86/SignalRTestProj

6、参考文章


一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。

RDIFramework.NET官方网站:http://www.rdiframework.net/

RDIFramework.NET官方博客:http://blog.rdiframework.net/

同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏!

RDIFramework.NET框架由海南国思软件科技有限公司专业团队长期打造、一直在更新、一直在升级,请放心使用!

欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。

扫描二维码立即关注

微信号:guosisoft

0
0
分享到:
评论

相关推荐

    WPF+SelfHost+HttpClient 模拟web通信

    在本文中,我们将深入探讨如何在WPF应用中利用SelfHost和HttpClient来模拟Web通信,同时结合Mvvmlight框架,实现一个简单的客户端-服务器通信示例。首先,让我们逐个解析这些关键技术点。 1. **WPF (Windows ...

    Video4.Demo3.SeltHost

    【标题】"Video4.Demo3.SeltHost" 指的可能是一个视频教程的第四部分,演示了如何自托管(Self-Host)一个应用程序或服务。在IT领域,自托管意味着在一个本地环境或者个人服务器上运行自己的软件,而不是依赖第三方...

    【ASP.NET编程知识】ASP.NET WebAPi(selfhost)实现文件同步或异步上传.docx

    然后,后台代码创建了一个`HttpClient`实例,用来向自托管的WebAPI发送POST请求。`MultipartFormDataContent`用于包装文件内容,设置文件名,然后发送到WebAPI的指定路由。 **WebAPI的SelfHost模式** SelfHost模式...

    创建ASP-NET-Web-API-2.0应用实例.doc

    4. **SelfHost**:控制台应用,模拟自我托管的Web API,同样引用WebApi项目。 5. **WebApp**:ASP.NET Web应用,提供前端页面,通过Ajax调用Web API进行CRUD操作。 6. **ConsoleApp**:控制台应用,用于模拟远程调用...

    AppHost.rar

    `Main`方法通常会创建一个新的AppHost实例,这个实例是自定义的,可以根据应用的需求进行配置。 2. **配置加载**:AppHost可以读取项目配置,如`appsettings.json`或环境变量,来确定应用程序的行为。这包括服务...

    WebApi寄宿到控制台的一个程序

    1. 引入库:确保项目引用了Microsoft.AspNet.WebApi.SelfHost和Microsoft.Owin.Hosting这两个库。这两个库分别提供了WebApi的Self-Host支持和Owin中间件,后者是.NET平台的Web服务器抽象层。 2. 创建WebHost配置:...

    WCF服务宿主及其跨域问题解决实例

    1. **自承载(Self-Host)**:开发者可以在自己的应用程序(如控制台应用、Windows服务等)中直接启动和管理WCF服务。 2. **IIS(Internet Information Services)**:利用IIS作为Web服务器来托管WCF服务,适用于...

    aspnet web api 超实用案例

     10、自托管 (Self-Host) : Web API 除了可以托管在 IIS 中, 还可以托管在进程中,依旧可以使用路由以及其它的特性。 二、注意事项  1、开发环境为Visual Studio 2012,数据库为SqlServer2008,使用.net 4.0开发...

    WCF简单实例

    【WCF简单实例】本文将引导读者通过一个简单的WCF(Windows Communication Foundation)应用实例,了解如何构建并运行一个基于WCF的服务。WCF是一种微软提供的面向服务的通信框架,用于构建分布式应用程序,支持跨...

    微软新技术WCF介绍及实例演示

    WCF服务可以自我托管(Self-host),也可以通过Windows服务、IIS或Windows Process Activation Service(WAS)进行托管。其中,WAS在Windows XP和Server 2003上不可用,而IIS 6.0仅支持HTTP协议。 **WCF实例演示** ...

    HttpSelfHostC#.rar

    而iView是一个基于Vue.js的UI组件库,提供了一系列美观且易于使用的界面元素,能够快速构建出专业级别的前端应用。 在项目中,开发者可能通过`System.IO`类读取静态文件并将其内容作为HTTP响应的主体返回。例如,当...

    ASP.NET WebAPi(selfhost)实现文件同步或异步上传

    ASP.NET WebAPI(selfhost)实现文件同步或异步上传是一项关键的技术,它允许开发者创建一个独立于IIS的服务器,用于处理文件上传请求。在本文中,我们将深入探讨如何利用这一技术实现在WebAPI中处理文件上传,无论...

    (6):宿主(Hosting)-WCF课件

    除了自宿主之外,还可以选择使用IIS或WAS来托管WCF服务。这种方式适合于需要更高可用性、安全性以及易于管理的生产环境。在IIS中部署WCF服务通常会使用HTTP协议,并且可以利用IIS提供的各种功能,如负载均衡、认证...

    NancySelfHostRazorTest:测试Nancy Self Host,Nancy Razor和HtmlHelpers的简单解决方案

    在NancySelfHostRazorTest项目中,"Self Host"指的是将Nancy应用部署在自己的进程中,而不是传统的IIS等Web服务器上,这为开发者提供了更高的灵活性和部署自由度。 接下来,我们关注Razor视图引擎。Razor是一种简洁...

    Eclipse PDT Guide

    - **简单的自我托管(Simple self-hosting)**:这部分解释了如何使用简单的自我托管方式来运行插件。 - **二进制项目自我托管(Binary project self-hosting)**:这是一种更高级的自我托管方式,适用于大型项目。 ###...

    WCF教程案例

    服务宿主(Service Host)是运行服务的进程,它可以是IIS、自承载(Self-hosting)或其他支持WCF的服务宿主。 ```csharp public class CalculatorService : ServiceBase, ICalculator { public double Add(double ...

    一个WCF应用的完整演示

    WCF允许服务独立运行,不依赖于IIS,这通常通过使用`SelfHost`类实现。在独立服务中,开发者可以直接启动并管理服务实例,使其能够在非IIS环境中运行。 3. **WinForm客户端**: WcfWinForm项目可能是Windows Forms...

    php几个预定义变量$_SERVER用法小结

    这个信息可以帮助确定哪个虚拟主机正在处理请求,尤其是在同一服务器上托管多个网站的情况下。 3. `$_SERVER['PHP_SELF']`: 这个变量返回当前执行脚本的文件名,从根目录开始的完整路径。它不包含任何URL或请求参数...

Global site tag (gtag.js) - Google Analytics