博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用SignalR来同步更新Winfrom
阅读量:5143 次
发布时间:2019-06-13

本文共 7384 字,大约阅读时间需要 24 分钟。

之前写了个用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    {        ///         /// 在连接上时        ///         /// 
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 (); } /// /// 这是给客户来调用的 /// 当客户端的添加按钮点击后 /// 就调用此方法 /// 当在客户端绑定了下面的Update方法后 /// 会自动去调用Update方法 /// /// 操作标识符 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    {        ///         /// 创建一个静态的对象,方便给服务端调用        ///         internal static ServerFrm serverFrm { get; set; }        ///         /// 应用程序的主入口点。        ///         [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 ();            });        }         ///         /// 开启服务        ///         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);        }         ///         /// 向服务容器写入信息        ///         /// 信息        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    {        ///         /// 连接代理对象        ///         private IHubProxy hubProxy { get; set; }        ///         /// 绑定的服务器url        ///         private string ServerURI = System.Configuration.ConfigurationManager.AppSettings["url"];         ///         /// 连接对象        ///         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 == "1" )                {                    //则更新界面                    InitData ();                }            });            try            {                //开始连接                await hubConnection.Start ();            }            catch ( Exception ex )            {                this.Text = "服务器未连接上";                return;            }            this.Text = "服务器已连接上";        }         ///         /// 加载或更新datagridview        ///         private void InitData ()        {            //获取数据            DemoEntities demo = new DemoEntities ();            var list = demo.DemoTable.ToList ();            this.Invoke (new Action (() =>             {                 //绑定数据                 dataGridView1.DataSource = list;              }));         }         ///         /// 添加按钮        ///         ///         ///         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" , "1");        }         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中加入了服务端向客户端广播的一些代码

 

转载于:https://www.cnblogs.com/weifeng123/p/11038697.html

你可能感兴趣的文章
通过SQL Server 2008数据库复制实现数据库同步备份
查看>>
一些需要禁用的PHP危险函数
查看>>
Jedis Client的使用以及序列化
查看>>
OpenRisc-32-ORPSoC烧写外部spi flash
查看>>
java--让一个字符串反转
查看>>
将窗口和浏览器背景色改为豆沙色保护眼睛
查看>>
进程和线程
查看>>
interface——关于虚函数的内存分配
查看>>
二叉树还原(前序+中序推后序)
查看>>
【转】递归与优化:尾递归
查看>>
快速软件开发 学习笔记 之四
查看>>
c#导出Excel的方法
查看>>
《JavaScript高级程序设计》笔记:函数表达式(七)
查看>>
同步和异步关注的是消息通信机制,阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态...
查看>>
表单验证
查看>>
spring mvc 数据校验
查看>>
ANTLR4权威指南 - 第5章 设计语法
查看>>
Python enum 枚举 判断 key(键) 或者 value(值)是否在枚举中
查看>>
python3 的一些常见的小知识点
查看>>
rpm 校验
查看>>