之前写了个用Socket来更新多个Winfrom的试例,这两天看了下SignalR,也用这个来试一下

SignalR 地址:https://www.asp.net/signalr

我这个也是基于 https://code.msdn.microsoft.com/Using-SignalR-in-WinForms-f1ec847b 改的

有很多地方基本上不明白,现在也只处在稍微会用的一些阶段

话不多讲,先看代码

1.创建服务端

样子,基本上就这样,先贴代码

里面有两个类文件要注意 MyHub和Startup

using System.Threading.Tasks;
using Microsoft.AspNet.SignalR; namespace ServerFrm
{
public class MyHub:Hub
{
/// <summary>
/// 在连接上时
/// </summary>
/// <returns></returns>
public override Task OnConnected ()
{
///向服务端写入一些数据
Program.serverFrm.WriteToInfo ("客户端连接ID:" + Context.ConnectionId);
return base.OnConnected ();
} public override Task OnDisconnected (bool stopCalled)
{
///向服务端写入一些数据
Program.serverFrm.WriteToInfo ("客户端退出ID:" + Context.ConnectionId);
return base.OnReconnected ();
} /// <summary>
/// 这是给客户来调用的
/// 当客户端的添加按钮点击后
/// 就调用此方法
/// 当在客户端绑定了下面的Update方法后
/// 会自动去调用Update方法
/// </summary>
/// <param name="actionId">操作标识符</param>
public void Send(string actionId)
{
/// 这是给客户端来调用的
/// 在连接服务器之前就给连接代理绑定这个方法
/// 在客户端连接上此服务后
/// 客户端绑定此方法,并且传入一个标识符,本例为 "1"(代表要更新界面上的datagridview
Clients.All.Update (actionId);
}
}
}

在MyHub里就只有一个方法是给客户端调用的Send

等会就会在客户端里看到这个方法的调用场景

using Microsoft.Owin;
using Owin; [assembly: OwinStartup (typeof (ServerFrm.Startup))] namespace ServerFrm
{
public class Startup
{
public void Configuration (IAppBuilder app)
{
// 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
//设置可以跨域访问
app.UseCors (Microsoft.Owin.Cors.CorsOptions.AllowAll);
//映射到默认的管理
app.MapSignalR ();
}
}
}

Startup类,基本上我也弄不太明白,反正就这么写也不出错,但不写肯定是错<br><br>接着是服务端主要的代码

using System;
using System.Windows.Forms; namespace ServerFrm
{
static class Program
{
/// <summary>
/// 创建一个静态的对象,方便给服务端调用
/// </summary>
internal static ServerFrm serverFrm { get; set; }
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main ()
{
Application.EnableVisualStyles ();
Application.SetCompatibleTextRenderingDefault (false);
serverFrm = new ServerFrm ();
Application.Run (serverFrm);
}
}
}
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Owin.Hosting; namespace ServerFrm
{
public partial class ServerFrm : Form
{
public ServerFrm ()
{
InitializeComponent ();
} private IDisposable signalR { get; set; }
private string serverUrl { get; set; } = System.Configuration.ConfigurationManager.AppSettings["url"];
private void btnStart_Click (object sender , EventArgs e)
{
WriteToInfo ("正在连接中....");
btnStart.Enabled = false;
Task.Run (() =>
{
ServerStart ();
});
} /// <summary>
/// 开启服务
/// </summary>
private void ServerStart ()
{
try
{
//开启服务
signalR = WebApp.Start (serverUrl);
}
catch ( Exception ex )
{
//服务失败时的处理
WriteToInfo ("服务开启失败,原因:" + ex.Message);
this.Invoke (new Action (() =>
{
btnStart.Enabled = true;
}));
return;
}
//服务成功,继续下一步
this.Invoke (new Action (() =>
{
//启用停止按钮
btnStop.Enabled = true;
}));
WriteToInfo ("服务开启成功 : " + serverUrl);
} /// <summary>
/// 向服务容器写入信息
/// </summary>
/// <param name="msg">信息</param>
internal void WriteToInfo(string msg)
{
if ( richTextBox.InvokeRequired )
{
this.Invoke (new Action (() =>
{
WriteToInfo (msg);
}));
return;
}
richTextBox.AppendText (msg+Environment.NewLine);
} private void btnStop_Click (object sender , EventArgs e)
{
if ( signalR!=null )
{
signalR.Dispose ();
}
} private void ServerFrm_FormClosing (object sender , FormClosingEventArgs e)
{
btnStop_Click (this , new EventArgs ());
Close ();
}
}
}

服务端的代码很少,主要的就是开启服务而已

接着是客户端

using System;
using System.Linq;
using System.Windows.Forms;
using Microsoft.AspNet.SignalR.Client;
using Model; namespace ClinetFrm
{
public partial class Clinet : Form
{
/// <summary>
/// 连接代理对象
/// </summary>
private IHubProxy hubProxy { get; set; }
/// <summary>
/// 绑定的服务器url
/// </summary>
private string ServerURI = System.Configuration.ConfigurationManager.AppSettings["url"]; /// <summary>
/// 连接对象
/// </summary>
private HubConnection hubConnection { get; set; } public Clinet ()
{
InitializeComponent ();
} private void Clinet_Load (object sender , EventArgs e)
{
InitData ();
InitHub ();
} private async void InitHub ()
{
//创建连接对象
hubConnection = new HubConnection (ServerURI);
//绑定一个集线器
hubProxy = hubConnection.CreateHubProxy ("MyHub");
//注册服务端的方法,此方法请转至服务端MyHub.cs中查看
hubProxy.On ("Update" , (a) =>
{
//如果接收到的是"1"
if ( a == "" )
{
//则更新界面
InitData ();
}
});
try
{
//开始连接
await hubConnection.Start ();
}
catch ( Exception ex )
{
this.Text = "服务器未连接上";
return;
}
this.Text = "服务器已连接上";
} /// <summary>
/// 加载或更新datagridview
/// </summary>
private void InitData ()
{
//获取数据
DemoEntities demo = new DemoEntities ();
var list = demo.DemoTable.ToList ();
this.Invoke (new Action (() =>
{
//绑定数据
dataGridView1.DataSource = list; })); } /// <summary>
/// 添加按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAdd_Click (object sender , EventArgs e)
{
DemoEntities demo = new DemoEntities ();
demo.DemoTable.Add (new DemoTable ()
{
name = txtName.Text ,
value = txtVal.Text
});
demo.SaveChanges (); ///使用代理启动方法,启动的是服务端中的Send方法
///而在服务端中Send会调用Update方法
///因为我们在程序启动时连接上了服务端
///而且绑定了Update方法,所以服务端在接收到Send方法被调用的通知时
///会自动去广播所有已经连上服务端的客户端使其调用Update方法
hubProxy.Invoke ("Send" , "");
} private void Clinet_FormClosing (object sender , FormClosingEventArgs e)
{
if ( hubConnection != null )
{
hubConnection.Stop ();
hubConnection.Dispose ();
}
}
}
}

客户端界面

再来张动图演示一下

https://github.com/raozhihao/SignallR4WinformUpdateDemo

git地址

里面用了EF数据库,可以照着Model - > DemoTable.cs 中的字段在数据库中建一个

另外在git中加入了服务端向客户端广播的一些代码

利用SignalR来同步更新Winfrom的更多相关文章

  1. 利用SignalR来同步更新Winfrom小试

    之前写了个用Socket来更新多个Winfrom的试例,这两天看了下SignalR,也用这个来试一下 SignalR 地址:https://www.asp.net/signalr 我这个也是基于 ht ...

  2. 利用Pycharm部署同步更新Django项目文件

    利用Pycharm部署同步更新Django项目文件 这里使用同步更新的前提是你已经在服务器上上传了你的Django项目文件. 在"工具(Tools)"菜单中找到"部署(D ...

  3. 如何利用svn自动同步更新到网站服务器

    我们最终的目的是:当本地提交后,SVN服务器自动更新服务器端指定WEB目录内的文件 实现方法: 找到服务器端 SVN版本库所在的目录(目录名称是Repositories),这个目录是在安装Visual ...

  4. 利用svn自动同步更新到网站服务器 -- 网摘

    首先在服务器上安装VisualSVN Server ,根据提示选好安装的路径,一路确定.安装好后运行VisualSVN Server ,在Repositories上点击右键,选择create New ...

  5. 使用VS2015将解决方案同步更新到Github上

    如今开源已经是一种趋势与潮流了,今天就来谈一谈如何将利用VS将我们的解决方案同步更新到Github上. 第一步:登录自己的Github账号(没有的自行注册). 我的Github登录后的界面: 第二步: ...

  6. 【WPF】修改数据层ViewModel后,UI界面未同步更新

    界面:WPF(MVVM)中将集合类控件ItemsControl的ItemsSource绑定到了ViewModel中的ObservableCollection列表,ItemsControl.ItemTe ...

  7. rsync+inotify实现数据的实时同步更新

    rsync可以实现触发式的文件同步,但是通过crontab守护进程方式进行触发,同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变动时,就触发rsync同步,这样 ...

  8. Git同步更新操作GitHub和码云仓库上面的代码

    一.前言 问题: 小编在生活中,一般都是将代码保存到github上,但由于国内的码云仓库确实速度比github快很多,用起来也很方便,于是后来就慢慢转码云了,当然小编在github上的代码也不想放弃更 ...

  9. .NET基础篇——利用泛型与反射更新实体(ADO.NET Entity Framework)(转)

    自从ADO.NET Entity Framework面世以来,受到大家的热捧,它封装了大量代码生成的工具,用户只需要建立好实体之间的关系,系统就是会为用户自动成功了Add.Delete.CreateO ...

随机推荐

  1. 人人都是产品经理?关于PM你不知道的还有很多

    产品经理的职称最早出现在P&G宝洁公司,因效果非常显著,许多企业纷纷仿而效尤.硅谷知名的产品管理大师Marty Cagan在<Inspired: How To Create Produc ...

  2. iOS保持流畅有哪些秘诀? 除了黑科技GPU还有这些重要原因 期待安卓8.0流畅度逆袭

    经常有人提起iPhone使用起来要比Android手机流畅,现在谈谈为什么iOS使用中会让人觉得更加流畅一些.一方面iPhone的顶级硬件为iOS的流畅打好了基础,另一方面,专一定制的系统是保证体验的 ...

  3. 第六章 Python之迭代器与生成器

    迭代器 迭代:迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果是下一次重复的初始值 l=['a','b','c'] count=0 while count < len(l): pri ...

  4. npm run eject 命令后出现This git repository has untracked files or uncommitted changes错误

    npm run eject 暴露隐藏的文件,不可逆 结果出现下面的问题 This git repository has untracked files or uncommitted changes: ...

  5. Vue学习之路第十篇:简单计算器的实现

    前面九篇讲解了vue的一些基础知识,正所谓:学以致用,今天我们将用前九篇的基础知识,来模拟实现计算器的简单功能,项目价值不高,纯粹是为了加深掌握所学知识. 学前准备: 需要掌握JavaScript的e ...

  6. [Codeforces 115E]Linear Kingdom Races

    题目大意: 有n块地,初始是荒地.你可以把某些荒地开垦(需要花费相应的价值\(a_i\)(正整数)),然后这些荒地就可以种田. 现在有m年,每年要在l到r区间内种田,获得p(正整数)的价值(必须保证l ...

  7. qt 透明化方法汇总

    一. QT 透明设置 背景,标题栏透明,下级Widget,painter绘出来的(比如,drawtext,drawline)不透明 QWidget window; window.setWindowFl ...

  8. [luogu] P4040 [AHOI2014/JSOI2014]宅男计划(贪心)

    P4040 [AHOI2014/JSOI2014]宅男计划 题目背景 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY不得不依靠叫外卖来维持生计. 题目描述 外卖店一共有N种食物, ...

  9. 题解 CF821D 【Okabe and City】

    其实,这道题不用long long也能AC. 题意是给你一个矩阵,有一些格子被点亮有一些没有,每一次只能在被点亮的格子上面走. 然后你每一次都可以选择点亮一行或一排(非永久),现在问你最少点多少次可以 ...

  10. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

    Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 1.什么是Set?(what) Set是Collection容器的一个子接口,它不允许出现 ...