首页 技术 正文
技术 2022年11月12日
0 收藏 476 点赞 3,591 浏览 8185 个字

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

引入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<string, string> _nickNames = new Dictionary<string, string>();         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

添加聊天室网页

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

SignalR学习笔记(三)Self-Host

添加所需SignalR库

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

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

Install-package Microsoft.AspNet.SignalR.JS

添加聊天网页

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

  1. 原先我们引用<script src=”signalr/hubs”></script>需要替换为<script src=”http://localhost:9021/signalr/hubs”></script>
  2. 在创建Hub代理之前,需要设置SignalR服务器的地址

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

最终网页代码

<!DOCTYPE html><html><head>    <title>SignalR Simple Chat</title>    <style type="text/css">        .container {            background-color: #99CCFF;            border: thick solid #808080;            padding: 20px;            margin: 20px;        }    </style></head><body>    <div class="container">        <input type="text" id="message" />        <input type="button" id="sendmessage" value="Send" />        <input type="hidden" id="displayname" />        <ul id="discussion"></ul>    </div>    <script src="Scripts/jquery-1.6.4.min.js"></script>    <script src="Scripts/jquery.signalR-2.2.2.min.js"></script>    <!--<script src="signalr/hubs"></script>-->    <script src="http://localhost:9021/signalr/hubs"></script>     <script type="text/javascript">        $(function () {             $.connection.hub.url = 'http://localhost:9021/signalr';             //使用代理模式, 创建客户端的hub代理            var chat = $.connection.chatRoomHub;             //服务器Hub中, 调用ReceiveWelcomeMessage方法时, 会执行客户端的chat.client.receiveBroadcastMessage方法            chat.client.receiveBroadcastMessage = function (name, message) {                 //防JS输入                var encodedName = $('<div />').text(name).html();                var encodedMsg = $('<div />').text(message).html();                 $('#discussion').append('<li><strong>' + encodedName                    + '</strong>:  ' + encodedMsg + '</li>');            };             //服务器Hub中, 调用ReceiveWelcomeMessage方法时, 会执行客户端的chat.client.receiveWelcomeMessage方法            chat.client.receiveWelcomeMessage = function (message) {                var encodedMsg = $('<div />').text(message).html();                 $('#discussion').append('<li><strong style="color:blue">' + encodedMsg                    + '</strong></li>');            };             //服务器Hub中, 调用ReceivePrivateMessage方法时, 会执行客户端的chat.client.receivePrivateMessage方法            chat.client.receivePrivateMessage = function (name, message) {                var encodedName = $('<div />').text(name).html();                var encodedMsg = $('<div />').text(message).html();                 $('#discussion').append('<li><strong style="color: green">' + encodedName                    + '偷偷的跟你说</strong>:  ' + encodedMsg + '</li>');            };             //通过代理连接到服务器Hub            $.connection.hub.start().done(function () {                $('#sendmessage').click(function () {                    chat.server.send($('#displayname').val(), $('#message').val());                     $('#message').val('').focus();                });                 //连接成功后, 需要用户立刻输入昵称                $('#displayname').val(prompt('Enter your name:', ''));                chat.server.setNickName($('#displayname').val());                $('#message').focus();            });        });    </script></body></html>

启动程序,效果如下

SignalR学习笔记(三)Self-Host

酷炫功能

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

public class ChatRoomHub : Hub    {        private static Dictionary<string, string> _nickNames = new Dictionary<string, string>();         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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,496
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,909
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,743
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,496
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,134
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,298