很久之前发表过一篇名为《通过三个DEMO学会SignalR的三种实现方式》的文章,在那篇文章里面详细介绍了在WEB应用下的常用SignalR实现方法,而今天我们来利用SignalR来实现其它的一些用法,比如:B/S 与 C/S互相通讯,比如:C/S与C/S通讯。

一、B/S 与 C/S互相通讯(ASP.NET 向  Winform  广播消息),先看效果如下:

如上图所示,采用服务端发送消息(指在C#代码发送),然后winform接收消息。

如上图所示,采服客户端(浏览器)JS 代理对象发送消息,然后winform接收消息。

上述示例的实现代码如下:

ASP.NET 服务端代码:

MyHub:

    [HubName("myHub")]
public class MyHub : Hub
{
public static Action<string> SendMsgAction = null;
public MyHub()
{
SendMsgAction = new Action<string>(SendMsg);
} private void SendMsg(string msg)
{
Clients.All.RecvMsg(msg);
} [HubMethodName("broadcast")]
public void Broadcast(string msg)
{
if ("broadcast".Equals(Context.QueryString["identity"])) //只有带有广播者身份才能进行广播消息
{
SendMsg(msg);
}
} public override System.Threading.Tasks.Task OnConnected()
{
return base.OnConnected();
} [HubMethodName("testConnect")]
public void TestConnect()
{
System.Diagnostics.Debug.Write("ddd");
}
}

ASP.NET 页面:(演示就用了服务器控件,以便到服务端进行发送)

        <div>
广播消息:<input type="text" id="txtmsg" runat="server" />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="服务端发送" />
</div>

ASP.NET CS代码:

        protected void Button1_Click(object sender, EventArgs e)
{
if(MyHub.SendMsgAction!=null)
{
MyHub.SendMsgAction("服务端发送消息-" + txtmsg.Value);
}
}

 在这里特别说明一下,因为MyHub是有连接时才会生成实例,我们无法直接在服务端获取到MyHub的实例,所以采取了在MyHub构造函数时,将SendMsg暴露给静态的 SendMsgAction委托,这样服务端就可以直接通过判断SendMsgAction是否有订阅来决定是否可以发送消息。这是一个取巧的的方式,当然如果大家有更好的方法,欢迎交流。

通过浏览器发送实现方法与之前的文章介绍的相同,这里采用代理模式,ASP.NET页面代码如下:(不作过多介绍)

    <script src="<%=ResolveUrl("~/Scripts/jquery-1.10.2.min.js") %>" type="text/javascript"></script>
<script src="<%=ResolveUrl("~/Scripts/jquery.signalR-2.2.2.min.js") %>" type="text/javascript"></script>
<script src="<%=ResolveUrl("~/signalr/hubs") %>" type="text/javascript"></script> <div>
广播消息:<input type="text" id="txtmsg2" />
<input type="button" id="btnSend" value="客户端发送" />
</div> <script type="text/javascript">
$(function () { var myhub = $.connection.myHub;
$.connection.hub.qs = { "identity": "broadcast" };
$.connection.hub.start().done(function () {
$("#btnSend").click(function () {
var msg = $("#txtmsg2").val();
myhub.server.broadcast("客户端发送消息-" + msg)
.done(function () {
alert("发送成功!");
}).fail(function (e) {
alert(e);
$("#txtmsg2").focus();
});
});
}); });
</script>

 这里有一个注意点:我们在定义MyHub类时,按照CSharp的代码规范是:类名 及方法名首字母都大写,但JS自动生成的代理JS类及方法名却会变成JS的命规范,即:函数名首个字母是小写,如:MyHub -->myHub,所以为了便于兼容JS调用,在定义Hub类时,用上HubName及HubMethodName特性,指定统一名称。

winform客户端接收消息步骤:

1.通过NuGet安装SignalR.Client相关组件

2.Winform CS代码:

    public partial class Form1 : Form
{
private HubConnection connection = null;
private IHubProxy hubProxy = null;
private System.Threading.SynchronizationContext syncContext = null; public Form1()
{
InitializeComponent();
syncContext = System.Threading.SynchronizationContext.Current;
} private void Form1_Load(object sender, EventArgs e)
{
CreateHubConnection();
} /// <summary>
/// 创建Hub代理类,并启动
/// </summary>
private void CreateHubConnection()
{
connection = new HubConnection("http://localhost:3510/signalr");//SignalR服务端地址
hubProxy = connection.CreateHubProxy("MyHub");
hubProxy.On<string>("RecvMsg", RecvMsg); //订阅接收消息
connection.Start().Wait();
} /// <summary>
/// 接收SignalR服务端的消息
/// </summary>
/// <param name="msg"></param>
private void RecvMsg(string msg)
{
syncContext.Post((o) => {
textBox1.Text += string.Format("{0:yyyy-MM-dd HH:mm:ss}{1}\r\n", DateTime.Now, o);
}, msg);
} private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
connection.Dispose();
} private void button1_Click(object sender, EventArgs e)
{
hubProxy.Invoke("TestConnect");//调用SignalR服务端的方法
} }

 通过上述代码可以看出,与ASP.NET 页面生成的JS代理类的方式原理基本相同,都是通过代理类来与服务端进行交互,都是通过HTTP协议进行通讯。

 二、C/S 与 C/S 互相通讯(winform与winform),其实本质上服务端还是B/S,只不过我们采取了SignalR self Host(里面用到了OWIN self Host),也就是将网站寄宿到winform而矣,只是我们通过winform操作更方更而矣,效果如下:

winform服务端实现流程:

1.先通过NuGet 分别安装Microsoft.AspNet.SignalR、Microsoft.AspNet.SignalR Self Host,如下图示:

2.添加Startup类文件,并在里面添加映射SignalR,代码如下:(与ASP.NET服务端的Startup代码相同)

    public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}

3.编写OWIN 的寄宿代码,MyHub与上文中的相同,故不再贴出

    public partial class Form1 : Form
{
private IDisposable webHost = null; public static Form1 Current = null; public Form1()
{
InitializeComponent();
this.Text = "SignalR Winform服务端";
Current = this;
} private void Form1_Load(object sender, EventArgs e)
{
try
{
webHost = WebApp.Start<Startup>("http://localhost:3512");
label2.Text = "http://localhost:3512";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
try
{
webHost.Dispose();
}
catch
{ }
} private void button1_Click(object sender, EventArgs e)
{
if(MyHub.SendMsgAction!=null)
{
MyHub.SendMsgAction(textBox1.Text);
}
} public void ShowMsg(string msg)
{
this.Invoke(new MethodInvoker(() => {
listBox1.Items.Add(msg);
}));
}
}

 这里有几个小细节需要注意:

1.安装Microsoft.AspNet.SignalR后会在项目中生成Sciprts文件夹,这个在winform项目时就可以删除掉;

2.安装Microsoft.AspNet.SignalR Self Host后,编译可能无问题,但运行起来时,可能会报朱找到匹配的OWin程序集,这个是因为OWIN版本问题,只需单独再安装一下指定的OWIN版本即可。

SignalR的另类实现技巧的更多相关文章

  1. hw小技巧(转载)

    小弟也第一次参加hw,经过5天hw,确实也学到了许多的东西,但就本次分享而言,我分享一些我认为在hw里面值得注意的东西以及一些小技巧 0x01 信息收集 信息收集这个多西当然都是老生常谈了,你收集的东 ...

  2. 【linux草鞋应用编程系列】_6_ 重定向和VT100编程

    一.文件重定向     我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...

  3. 使用 Google Analytics 跟踪 JavaScript 错误

    Google Analytics(谷歌分析)不仅仅是一个流量统计工具,你还可以用它来测量广告活动的有效性,跟踪用户多远到所需的页面流(从点击广告到购物车到结账页面)获取,并基于用户的信息设置浏览器和语 ...

  4. 重定向和VT100编程

    重定向和VT100编程 一.文件重定向     我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "h ...

  5. 高效率使用google,国外搜索引擎,国内顺利使用Google的另类技巧,可用谷歌镜像, 可用google学术, 如何使用robots不让百度和google收录

    Google良好的搜索和易用性已经得到了广大网友的欢迎,但是除了我们经常使用的Google网站.图像和新闻搜索之外,它还有很多其他搜索功能和搜索技巧.如果我们也能充分利用,必将带来更大的便利.这里我介 ...

  6. 国内顺利使用Google的另类技巧

    在特殊的地方和特殊的时间,流畅顺利使用Google的方法也会变得很特殊.本文不定期保持维护更新,删除不能用的,增加新的网址. 分享一些奇葩的Google使用方法,通过下列网址也可以使用Google来搜 ...

  7. (搬运工)国内顺利使用Google的另类技巧

    在特殊的地方和特殊的时间,流畅顺利使用Google的方法也会变得很特殊.分享一些奇葩的Google使用方法,通过下列网址也可以使用Google来搜索:http://www.GoogleStable.c ...

  8. Mplayer另类在线播放影音文件技巧【转】

    http://www.linuxsir.org/bbs/showthread.php?t=254467 本文介绍的Mplayer在线播放的方法,不是指在浏览器中安装Mplayer插件这种方法,而是在命 ...

  9. 【安卓逆向】反编译ELF的另类技巧

    IDA 反编译 ObjDump反编译 ObjDump是ndk环境自带的一个脚本,在android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebu ...

随机推荐

  1. NOIP2017普及组解题报告

    刚参加完NOIP2017普及,只考了210,于是心生不爽,写下了这篇解题报告...(逃 第一次写博,望dalao们多多指导啊(膜 第一题score,学完helloworld的人也应该都会吧,之前好多人 ...

  2. Codeforces 869E The Untended Antiquity

    题意:给定一个网格图,三种操作:1.在(r1,c1,r2,c2)处建围墙.2.删除(r1,c1,r2,c2)处的围墙.3.询问两点是否可达 思路比较巧妙,将围墙内的点赋加一个权值,询问的时候判断两个点 ...

  3. 数据模型与查询语言 ------《Designing Data-Intensive Applications》读书笔记2

    数据模型是开发软件的最重要的部分,因为它们对应用程序有着深远的影响:不仅是软件的编写方式,而且也影响我们如何解决的问题的方式.第二篇读书笔记,我们聊一聊数据模型的设计. 1.数据模型的分层 作为一个开 ...

  4. mustache.js 使用

    对于mustache模板,我是属于即用即查的方法,以下记录仅是我常用的方式.方便以后使用时不用再去项目中去找,因为真的不好找.(此处 -->serious 脸) 当需要渲染一些数据列表的时候,使 ...

  5. Spark之搜狗日志查询实战

    1.下载搜狗日志文件: 地址:http://www.sogou.com/labs/resource/chkreg.php 2.利用WinSCP等工具将文件上传至集群. 3.创建文件夹,存放数据: mk ...

  6. Azure ARM (19) 将传统的ASM VM迁移到ARM VM (2)

    <Windows Azure Platform 系列文章目录> 因为我们在上一节中: Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1) 已经创建了Azure V ...

  7. 我这样减少了26.5M Java内存!

    WeTest 导读 历时五天的内存优化已经结束,这里总结一下这几天都做了什么,有哪些收获.优化了,或可以优化的地方都有哪些.(因为很多事还没做,有些结论需要一定样本量才能断定,所以叫一期)一期优化减少 ...

  8. quickhybrid】如何实现一个Hybrid框架

    章节目录 [quickhybrid]如何实现一个跨平台Hybrid框架 [quick hybrid]架构一个Hybrid框架 [quick hybrid]H5和Native交互原理 [quick hy ...

  9. Ajax中的JSON格式与php传输过程的浅析

    在Ajax中的JSON格式与php传输过程中有哪些要注意的小地方呢? 先来看一下简单通用的JSON与php传输数据的代码 HTML文件: <input type="button&quo ...

  10. 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul

    通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...