原文:WPF+SignalR实现用户列表实时刷新

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lordwish/article/details/51789884

在实时通信应用中,最常用也最基本的就是终端列表的实时刷新,也就是当客户端上线或下线时,服务端都会向全体客户端推送通知及新的在线客户端列表。


客户端类

    public partial class ClientModel
{
public ClientModel()
{
}
private string _client_name;
private string _client_ip="192.168.1.1";
private string _connectionid;
//计算机名
public string ClientName
{
set { _client_name = value; }
get { return _client_name; }
}
//计算机IP
public string ClientIP
{
set { _client_ip = value; }
get { return _client_ip; }
}
//通信连接id
public string ConnectionId
{
set { _connectionid = value; }
get { return _connectionid; }
}
}

服务端

服务端创建

服务端创建请参考下面文章

[使用WPF创建SignalR服务端]

服务端方法

在MyHub类中添加服务端方法。对于客户端上线建立连接,服务端方法有两种,一种是重载Hub类的OnConnected方法,另一种是就是自定义的方法了。OnConnected方法在客户端与服务端建立通信连接时会被立即调用,但我们很多时候是先建立连接等到用户验证后再登录刷新在线终端列表,也就是说两者的触发时机不同,但基本原理是一致的。

首先定义一个变量来存储在线终端信息:

public List<ClientModel> ClientList = new List<ClientModel>();

OnConnected方法

        public override Task OnConnected()
{
ClientModel client = new ClientModel
{
ClientName = GetName(),//获取远程计算机名
ClientIP = GetIp(),//获取远程计算机IP
ConnectionId=Context.ConnectionId
};
foreach (ClientModel m in ClientList)
{
if (m.ClientIp==client.ClientIp)
{
ClientList.Remove(m);
break;
}
}
ClientList.Add(client);
Clients.All.getclientlist(ClientList);
string output = string.Format("用户 {0} 上线,IP:{1}", client.ClientName, client.ClientIP);
Application.Current.Dispatcher.Invoke(() =>
{
((MainWindow)Application.Current.MainWindow).WriteToConsole(output);
});
return base.OnConnected();
}

自定义方法GetClientList

public Task GetClientList(string clientname,string clientmac,string clientip)
{
ClientModel client = new ClientModel
{
ClientName = clientname,
ClientIP = clientip,
ConnectionId=Context.ConnectionId
};
foreach (Model.ClientModel m in ClientList)
{
if (m.ClientIp==clientip)
{
ClientList.Remove(m);
break;
}
}
ClientList.Add(client);
Task all = Clients.All.getclientlist(ClientList);
string output = string.Format("用户 {0} 上线,IP:{1}", client.ClientName, client.ClientIP);
Application.Current.Dispatcher.Invoke(() =>
{
((MainWindow)Application.Current.MainWindow).WriteToConsole(output);
});
return all;
}

客户端

创建WPF项目ClientApp(不低于.NET Framework 4.0),使用NuGet管理器引用SignalR程序包,只需要引用Microsoft.AspNet.SignalR.Client即可。使用设计器添加一个数据列表(DataGrid或ListView)用于绑定在线客户端列表。

创建并启动通信连接

    public static HubConnection Connection = new HubConnection(ConfigurationManager.AppSettings["ServiceUri"]);
public static IHubProxy MyHub; public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ConnectAsync();
} private async void ConnectAsync()
{
MyHub = Connection.CreateHubProxy("MyHub");
try
{
await Connection.Start();//建立连接
}
catch (Exception)
{
throw;
}
}

针对服务端的实现方法,客户端也有不同的方法,如果使用服务端的OnConnected方法,上面的方法足够了,因为客户端的基本信息都是包含在Context中的,客户端与服务端建立连接时,服务端可以从Context中获取客户端信息。当然也可以写个自定义方法连接服务端的GetClientList方法。

private void ClientOnline()
{
string clientname=GetName();
string clientip=GetIP();
MyHub.Invoke("",clientname,clientip);
}

在通信连接建立后或在用户执行相应操作后执行此方法,向服务端发送客户端信息,服务端经过处理后将更改后的在线客户端列表广播至各客户端,现在缺少的就是客户端监听服务端的方法了。监听方法本质是一个长轮询,可以在其中接受服务端推送的数据并执行相应操作。

public MainWindow()
{
InitializeComponent();
ConnectAsync();
ConnectListener();
}
public void ConnectListener()
{
MyHub.On<List<ClientModel>>("getclientlist", list =>{
//数据绑定
this.Dispatcher.Invoke(delegate{
dgList.ItemsSource = list;
})
});
}

最后就需要关闭终端下线的方法了

服务端:

        public override Task OnDisconnected(bool stopCalled)
{
Model.ClientModel client = new Model.ClientModel();
foreach (Model.ClientModel m in ClientList)
{
if (m.ConnectionId==Context.ConnectionId)
{
client = m;
ClientList.Remove(m);
break;
}
}
Clients.All.getuserlist(ClientList);
string output = string.Format("用户 {0} 下线,IP:{1}", client.ClientName, client.ClientIP);
Application.Current.Dispatcher.Invoke(() =>
{
((MainWindow)Application.Current.MainWindow).WriteToConsole(output);
});
return base.OnDisconnected(stopCalled);
}

客户端

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Connection.Stop();
Connection.Dispose();
}

其实上面只是简单的示例,而实际的业务场景会更复杂,但其基本原理是一致的,多多思考,可以扩展更多。

WPF+SignalR实现用户列表实时刷新的更多相关文章

  1. 使用SignalR实现比特币价格实时刷新

    ASP.NET SignalR是微软支持的一个运行在 Dot NET 平台上的 HTML Websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重 ...

  2. C#开发微信门户及应用(4)--关注用户列表及详细信息管理

    在上个月的对C#开发微信门户及应用做了介绍,写过了几篇的随笔进行分享,由于时间关系,间隔了一段时间没有继续写这个系列的博客了,并不是对这个方面停止了研究,而是继续深入探索这方面的技术,为了更好的应用起 ...

  3. 使用SignalR+Asp.net创建实时聊天应用程序

    一.概述: 使用 ASP.NET 那么 SignalR 2 创建一个实时聊天应用程序.将 SignalR 添加 MVC 5 应用程序中,并创建聊天视图发送并显示消息. 在Demo中,将学习Signal ...

  4. 基于Redis的在线用户列表解决方案

    前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案可以采用SessionListener来完成 ...

  5. [项目回顾]基于Redis的在线用户列表解决方案

    迁移:基于Redis的在线用户列表解决方案 前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案 ...

  6. SignalR指定用户推送消息

    一.首先,在MVC项目中安装SingalR包(SingalR2.0需要.net4.5以上,VS2010可以安装1.1.3版本,本例为VS2010+SignalR1.1.3). 打开工具-NuGet程序 ...

  7. 【Java框架型项目从入门到装逼】第十四节 查询用户列表展现到页面

    这一节,我们来实现一下用户列表搜索,最终的效果如下: 这边我们要使用easyUI给我们提供的datagrid组件. HTML结构如下 <!-- 数据列表 --> <table id= ...

  8. Vue+WebSocket 实现页面实时刷新长连接

    最近vue项目要做数据实时刷新,折线图每秒重画一次,数据每0.5秒刷新一次,说白了就是实时刷新,因为数据量较大,用定时器估计页面停留一会就会卡死... 与后台人员讨论过后决定使用h5新增的WebSoc ...

  9. gulp使用 实现文件修改实时刷新

    gulp例子:https://github.com/Aquarius1993/gulpDemo 淘宝镜像:$ npm install -g cnpm --registry=https://regist ...

随机推荐

  1. matlab 文件路径问题

    1. fullfile:路径补全 f = fullfile(filepart1,...,filepartN) 显然可变参数之间填充的路径分隔符(path separator),会根据操作系统而变化: ...

  2. Flume Source官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于flume官网 http://flume.apache.org/FlumeUserGuide.html Flume Sources Avro Source Thrift ...

  3. 洛谷 P2693 [USACO1.3]号码锁 Combination Lock

    P2693 [USACO1.3]号码锁 Combination Lock 题目描述 农夫约翰的奶牛不停地从他的农场中逃出来,导致了很多损害.为了防止它们再逃出来,他买了一只很大的号码锁以防止奶牛们打开 ...

  4. Dcloud开发webApp踩过的坑

    Dcloud开发webApp踩过的坑 一.总结 一句话总结:HTML5+扩展了JavaScript对象plus,使得js可以调用各种浏览器无法实现或实现不佳的系统能力,设备能力如摄像头.陀螺仪.文件系 ...

  5. __INLINE

  6. HDU 1166 敌兵布阵 树状数组||线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1166 题目大意: 给定n个数的区间N<=50000,还有Q个询问(Q<=40000)求区间和. 每个 ...

  7. 【AtCoder Beginner Contest 074 B】Collecting Balls (Easy Version)

    [链接]h在这里写链接 [题意] 看懂题目之后就会发现是道大水题. [题解] 在这里写题解 [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/stdc++.h&g ...

  8. 首次使用vim

    不管是linux还是cygwin,刚安装完系统之后使用vim时都需要对vim进行配置.未配置的情况下,象方向键.回车键.退格键都不会是正常的反应.因为vim默认使用了vi的操作模式. 不多说,上代码. ...

  9. 前端项目课程7 banner设计注意事项

    前端项目课程7 banner设计注意事项 一.总结 一句话总结: 1.每个部分的里面的部分可以用相同的名字么,如何修改样式呢? 可以, 用模块名 + 比如上中下(top middle bottom) ...

  10. 使用wepy开发微信小程序商城第三篇:购物车(布局篇)

    使用wepy开发微信小程序商城 第三篇:购物车(布局篇) 前两篇如下: 使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 基于上两篇内容,开始 ...