史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例
1、概述
通过前面几篇文章
史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式
史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式
RDIFramework.NET敏捷开发框架通过SignalR技术整合即时通讯(IM)
我们对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服务中等。
- 其他的一些原因....
本篇主要讲解以下内容:
- 使用Self-Host方式创建SignalR服务端
- 用javascript客户端访问SignalR Self-Host服务端
- 用WinForm客户端接收SignalR Self-Host服务端消息
2、使用Self-Host方式创建SignalR服务端
为了更简单的说明self-host托管的方式,我们用控制台应用程序来做演示。当然我们也可以自托管到Windows服务中去,如果你更希望托管到Windows服务,可以参考Self-Hosting SignalR in a Windows Service
在上一项目的基础上,我们新建一个名为:SignalRSelfHost的控制台应用程序,如下所所示:
要使用Selft-Host宿主SignalR,必须引用Microsoft.AspNet.SignalR.SelfHost包。我们在程序包管理控制台输入以下命令安装SelfHost包。
Install-Package Microsoft.AspNet.SignalR.SelfHost
要想支持跨域访问,还需要安装
Install-Package Microsoft.Owin.Cors
如果用命令的方式安装失败,我们可以用NuGet的方式安装,如下图所示。
编写代码如下:
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控制台服务端如下。
可以看到我们的控制台服务端已经成功启动起来了。
3、用javascript客户端访问SignalR Self-Host服务端
3.1、新建SignalRSelfHostJSClient的MVC空项目
3.2、添加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>: ' + 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控制台服务端后,再运行两个我们的测试客户端,分别输入不同的用户名,试试聊天的效果,如下图所示。
4、用WinForm客户端接收SignalR Self-Host服务端消息
4.1、新建SignalRSelfHost的WinForm项目
4.2、使用NuGet安装Microsoft.AspNet.SignalR.Client包
4.3、制作测试界面如下:
编写界面代码如下:
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、运行效果:
通过以上的详细讲解,我们已经非常清楚的了解了如何通过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),及时了解最新动态。
扫描二维码立即关注
史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例的更多相关文章
- SignalR系列教程:SignalR快速入门
---恢复内容开始--- 本篇是SignalR系列教程的第一篇,本篇内容介绍了如何创建SignalR应用,如何利用SignalR搭建简易的聊天室等,本篇内容参考自:http://www.asp.net ...
- 史上最全面的SignalR系列教程-5、SignalR 实现一对一聊天
1.概述 通过前面几篇文章 史上最全面的SignalR系列教程-1.认识SignalR 史上最全面的SignalR系列教程-2.SignalR 实现推送功能-永久连接类实现方式 史上最全面的Signa ...
- 史上最全面的SignalR系列教程-6、SignalR 实现聊天室
1.概述 通过前面几篇文章对SignalR的详细介绍.我们知道Asp.net SignalR是微软为实现实时通信的一个类库.一般情况下,SignalR会使用JavaScript的长轮询(long po ...
- 史上最全面的SignalR系列教程-目录汇总
1.引言 最遗憾的不是把理想丢在路上,而是理想从未上路. 每一个将想法变成现实的人,都值得称赞和学习. 致正在奔跑的您! 2.SignalR介绍 SignalR实现服务器与客户端的实时通信 ,她是一个 ...
- 史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式
1.概述 通过上篇史上最全面的SignalR系列教程-1.认识SignalR文章的介绍,我们对SignalR技术已经有了一个全面的了解.本篇开始就通过SignalR的典型应用的实现方式做介绍,例子虽然 ...
- 史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式
1.概述 通过前两篇 史上最全面的SignalR系列教程-1.认识SignalR 史上最全面的SignalR系列教程-2.SignalR 实现推送功能-永久连接类实现方式 文章对SignalR的介绍, ...
- jquery系列教程7-自定义jquery插件全解:对象函数、全局函数、选择器
点击打开: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件操作全解 jquery系列教程5-动 ...
- [整理]Node入门 » 一本全面的Node.js教程 - Demo实践所遇到的问题
花了一个上午看完[转载]Node入门 » 一本全面的Node.js教程 根据里面的Demo自己手动实现过程中还是遇到了些问题,特整理在此. <1>.由于node.msi安装包已经自动添加了 ...
- 狗鱼IT教程:推介最强最全的Spring系列教程
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建. 简单来说,Spring是一个分层的JavaSE/EEfull-stack( ...
随机推荐
- EnjoyingSoft之Mule ESB开发教程第三篇:Mule message structure - Mule message结构
目录 1. 探索Mule Message结构 2. Mule Message的Payload 3. Mule Message的Property 4. Mule Message的Attachment 5 ...
- https://www.cnblogs.com/M-LittleBird/p/5902850.html
https://www.cnblogs.com/M-LittleBird/p/5902850.html
- React躬行记(9)——组件通信
根据组件之间的嵌套关系(即层级关系)可分为4种通信方式:父子.兄弟.跨级和无级. 一.父子通信 在React中,数据是自顶向下单向流动的,而父组件通过props向子组件传递需要的信息是组件之间最常见的 ...
- 个人永久性免费-Excel催化剂功能第105波-批量调整不规范的图形对象到单一单元格内存储
在日常制表过程中,一个不得不面对的问题,许多的工作起点是基于其他人加工过的表格,无论自己多大的本领,面对不规范的其他人的制作的表格,经过自己的手,该擦的屁股还是要自己去亲手去擦,而带出来的也只会是一堆 ...
- Quartus ii调试技巧_01
前几天李主任跟我分享了一些特别好用的调试技巧: 1)System Sources and Probes Editor---类似于人为设置触发条件,创建虚拟按键等功能,这段时间一直在做一个电机的驱动,板 ...
- JSP+java上传图片到服务器,并将地址保存至MYSQL + JSP网页显示服务器的图片
这两天遇到个需求——用户头像修改功能. 查了好多资料,不是代码不全,就是某些高端框架,卡了好久,今已实现,分享给大家,如果有更好的方法,非常感谢可以在下方评论区写出 一.整体项目架构 二.web.xm ...
- @Validated和@Valid的区别?校验级联属性(内部类)
每篇一句 NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JSR303.JSR349.JSR380) ...
- 【MySQL】添加多个字段
MySQL 遇到了添加多个字段的问题,尝试了几次,搞定了,记录下. 示例代码如下: alter table ad_data add ( exposure_count bigint(20) defaul ...
- 动态开内存(malloc与calloc)
malloc与calloc 1.函数原型 #include<stdlib.h> void *malloc(unsigned int size); //申请size字节的内存 voi ...
- Asp.Net Core 发布到 Docker(Linux Centos 虚拟机,使用Dockerfile)
实践一下 Asp.Net Core (基于.net core 2.2)部署到Docker 一.准备工作: 1. 使用Virtualbox创建一个Centos系统的虚拟机,并安装docker和vim 2 ...