SignalR学习笔记(三)Self-Host

SignalR可以借助Owin摆脱对IIS的依赖,实现Self-Host,使得SignalR有了部署在非Windows平台的可能。

 

什么是Owin

Owin的英文全称是Open Web Interface for .NET, 他定义了Web应用程序和Web服务器之间的接口。他的作用就是解除了Web应用程序与Web服务器之间的耦合,从而使Web应用程序不再依赖于具体的Web服务器,已ASP.NET应用程序为例,以前需要依赖于IIS,  引入Owin之后,他只依赖与Owin提供的接口,所以所有实现Owin接口的Web服务器都可以替换掉IIS。

 

如何在控制台程序中实现SignalR Self-Host

 

创建一个空的控制台程序

 

SignalR学习笔记(三)Self-Host_第1张图片

引入SignalR SelfHost包

打开Package Manager Console面板,输入以下命令安装SignalR Self Host包。

Install-package Microsoft.AspNet.SignalR.SelfHost

 

其他可能需要引入的包

因为如果使用Self-Host, 通常会指定一个独立的端口或者独立ip,这样就会出现跨域的问题,如果出现跨域问题,请引入Owin的CORS包

Install-package Microsoft.Owin.Cors

使用Owin启动一个Web服务器

 

    class Program

    {

        static void Main(string[] args)

        {

            string url = "http://localhost:9021";

            using (WebApp.Start(url))

            {

                Console.WriteLine("Server running on {0}", url);

                Console.ReadKey();

            }

        }

}

 

 

添加Owin启动类

 

 

    class Startup

    {

        public void Configuration(IAppBuilder app)

        {

            //允许所有域名跨域访问

            app.UseCors(CorsOptions.AllowAll);

 

            //启动SignalR

            app.MapSignalR();

        }

    }


 

 

添加Hub代码

这里我们可以直接把学习笔记(一)中的Hub代码直接Copy过来,最终的的Self Host代码如下

 

 

using Microsoft.AspNet.SignalR;

using Microsoft.Owin.Cors;

using Microsoft.Owin.Hosting;

using Owin;

using System;

using System.Collections.Generic;

using System.Linq;

 

namespace SignalRSelfHost

{

    class Program

    {

        static void Main(string[] args)

        {

            string url = "http://localhost:9021";

            using (WebApp.Start(url))

            {

                Console.WriteLine("Server running on {0}", url);

                Console.ReadKey();

            }

        }

    }

 

    class Startup

    {

        public void Configuration(IAppBuilder app)

        {

            //允许所有域名跨域访问

            app.UseCors(CorsOptions.AllowAll);

 

            //启动SignalR

            app.MapSignalR();

        }

    }

 

    public class ChatRoomHub : Hub

    {

        private static Dictionary _nickNames = new Dictionary();

 

        public void SetNickName(string nickName)

        {

            //当Hub启动完毕,每个连接到这个Hub的客户端都会自动分配一个唯一的ConnectionId。

            //当SignalR向指定客户端推送消息的时候,需要指定ConnectionId, 所以这里需要记录一下每个昵称对应的客户端ConnectionId

            _nickNames.Add(Context.ConnectionId, nickName);

 

            //当用户设置昵称之后,需要发送欢迎信息到所有的用户客户端,调用客户端receiveWelcomeMessage方法显示欢迎信息

            Clients.All.ReceiveWelcomeMessage($"{nickName}进入聊天室。");

        }

 

        public void Send(string nickName, string message)

        {

            if (string.IsNullOrWhiteSpace(nickName) || string.IsNullOrWhiteSpace(message))

            {

                //如果用户昵称或者消息不存在,就不做任何操作

                return;

            }

 

            if (message.StartsWith("to") && message.Split(' ').Length == 3)

            {

                //私聊消息

                var toUserName = message.Split(' ')[1];

 

                if (_nickNames.ContainsValue(toUserName))

                {

                    var connectionId = _nickNames.First(p => p.Value == toUserName).Key;

 

                    if (!string.IsNullOrWhiteSpace(connectionId) && connectionId != Context.ConnectionId)

                    {

                        Clients.Client(connectionId).ReceivePrivateMessage(nickName, message.Split(' ')[2]);

                    }

                }

            }

            else

            {

                //普通广播消息

                if (_nickNames.ContainsValue(nickName))

                {

                    Clients.All.ReceiveBroadcastMessage(nickName, message);

                }

            }

        }

    }

}


 

运行程序

按Ctrl+F5启动控制台程序, 显示Server running on xxxxx.表明服务器启动成功。

 SignalR学习笔记(三)Self-Host_第2张图片

 

添加聊天室网页

 

这里需要重新创建一个空的Web程序

SignalR学习笔记(三)Self-Host_第3张图片

添加所需SignalR库

因为SignalR服务器已经移到了控制台程序当中,所以这里不需要应用Microsft.AspNet.SignalR库了

 

这里仅需要引入SignalR的客户端脚本

Install-package Microsoft.AspNet.SignalR.JS

 

添加聊天网页

这里我们将学习笔记(一)的代码直接copy过来,稍作修改。

  1. 原先我们引用需要替换为
  2. 在创建Hub代理之前,需要设置SignalR服务器的地址

$.connection.hub.url = 'http://localhost:9021/signalr';

 

 

最终网页代码

 

 







    SignalR Simple Chat

    





    
                               
       
                         


     

     

    启动程序,效果如下

     

    SignalR学习笔记(三)Self-Host_第4张图片

    酷炫功能

    使用Self-Host之后,我们可以实现一个很酷炫的功能,在控制台程序中监控用户的输入

     

     

    public class ChatRoomHub : Hub
    
        {
    
            private static Dictionary _nickNames = new Dictionary();
    
     
    
            public void SetNickName(string nickName)
    
            {
    
                //当Hub启动完毕,每个连接到这个Hub的客户端都会自动分配一个唯一的ConnectionId。
    
                //当SignalR向指定客户端推送消息的时候,需要指定ConnectionId, 所以这里需要记录一下每个昵称对应的客户端ConnectionId
    
                _nickNames.Add(Context.ConnectionId, nickName);
    
     
    
                //当用户设置昵称之后,需要发送欢迎信息到所有的用户客户端,调用客户端receiveWelcomeMessage方法显示欢迎信息
    
                Clients.All.ReceiveWelcomeMessage($"{nickName}进入聊天室。");
    
                Console.WriteLine($"{nickName}进入聊天室。");
    
            }
    
     
    
            public void Send(string nickName, string message)
    
            {
    
                if (string.IsNullOrWhiteSpace(nickName) || string.IsNullOrWhiteSpace(message))
    
                {
    
                    //如果用户昵称或者消息不存在,就不做任何操作
    
                    return;
    
                }
    
     
    
                if (message.StartsWith("to") && message.Split(' ').Length == 3)
    
                {
    
                    //私聊消息
    
                    var toUserName = message.Split(' ')[1];
    
     
    
                    if (_nickNames.ContainsValue(toUserName))
    
                    {
    
                        var connectionId = _nickNames.First(p => p.Value == toUserName).Key;
    
     
    
                        if (!string.IsNullOrWhiteSpace(connectionId) && connectionId != Context.ConnectionId)
    
                        {
    
                            Clients.Client(connectionId).ReceivePrivateMessage(nickName, message.Split(' ')[2]);
    
                            Console.WriteLine($"{nickName}偷偷对{toUserName}说:{message}");
    
                        }
    
                    }
    
                }
    
                else
    
                {
    
                    //普通广播消息
    
                    if (_nickNames.ContainsValue(nickName))
    
                    {
    
                        Clients.All.ReceiveBroadcastMessage(nickName, message);
    
                        Console.WriteLine($"{nickName}对大家说:{message}");
    
                    }
    
                }
    
            }
    
        }

    SignalR学习笔记(三)Self-Host_第5张图片
     

    你可能感兴趣的:(SignalR学习笔记(三)Self-Host)