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; }
}
}
服务端
服务端创建
服务端创建请参考下面文章
服务端方法
在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实现用户列表实时刷新的更多相关文章
- 使用SignalR实现比特币价格实时刷新
ASP.NET SignalR是微软支持的一个运行在 Dot NET 平台上的 HTML Websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重 ...
- C#开发微信门户及应用(4)--关注用户列表及详细信息管理
在上个月的对C#开发微信门户及应用做了介绍,写过了几篇的随笔进行分享,由于时间关系,间隔了一段时间没有继续写这个系列的博客了,并不是对这个方面停止了研究,而是继续深入探索这方面的技术,为了更好的应用起 ...
- 使用SignalR+Asp.net创建实时聊天应用程序
一.概述: 使用 ASP.NET 那么 SignalR 2 创建一个实时聊天应用程序.将 SignalR 添加 MVC 5 应用程序中,并创建聊天视图发送并显示消息. 在Demo中,将学习Signal ...
- 基于Redis的在线用户列表解决方案
前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案可以采用SessionListener来完成 ...
- [项目回顾]基于Redis的在线用户列表解决方案
迁移:基于Redis的在线用户列表解决方案 前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案 ...
- SignalR指定用户推送消息
一.首先,在MVC项目中安装SingalR包(SingalR2.0需要.net4.5以上,VS2010可以安装1.1.3版本,本例为VS2010+SignalR1.1.3). 打开工具-NuGet程序 ...
- 【Java框架型项目从入门到装逼】第十四节 查询用户列表展现到页面
这一节,我们来实现一下用户列表搜索,最终的效果如下: 这边我们要使用easyUI给我们提供的datagrid组件. HTML结构如下 <!-- 数据列表 --> <table id= ...
- Vue+WebSocket 实现页面实时刷新长连接
最近vue项目要做数据实时刷新,折线图每秒重画一次,数据每0.5秒刷新一次,说白了就是实时刷新,因为数据量较大,用定时器估计页面停留一会就会卡死... 与后台人员讨论过后决定使用h5新增的WebSoc ...
- gulp使用 实现文件修改实时刷新
gulp例子:https://github.com/Aquarius1993/gulpDemo 淘宝镜像:$ npm install -g cnpm --registry=https://regist ...
随机推荐
- amazeui学习笔记二(进阶开发1)--项目结构structure
amazeui学习笔记二(进阶开发1)--项目结构structure 一.总结 1.项目结构:是说的amazeui在github上面的项目结构,二次开发amazeui用 二.项目结构structure ...
- vue .sync 修饰符和自定义v-model的使用
VUE 是单向数据流 当我们需要对一个 prop 进行"双向绑定"时 vue 修饰符.sync 子组件:this.$emit('update:visible', visible), ...
- GO语言学习(十二)Go 语言函数
Go 语言函数 函数是基本的代码块,用于执行一个任务. Go 语言最少有个 main() 函数. 你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务. 函数声明告诉了编译器函数的名称,返回 ...
- amazeui学习笔记--css(常用组件13)--进度条Progress
amazeui学习笔记--css(常用组件13)--进度条Progress 一.总结 1.进度条基本使用:进度条组件,.am-progress 为容器,.am-progress-bar 为进度显示信息 ...
- Altium Designer如何统一改变pcb状态下的原件标号位置
原创 我用的是Altium Designer16版本 变成 步骤如下: 选中标号 右击 下边一步很重要: 点击应用和确定 在之后弹出的对话框中选则你要改变的位置,我这里是把标号改变到原件的右侧: 等待 ...
- easyui datagrid editor checkbox 单击事件
Easyui datagrid treegrid中能够为行追加checkbox元素.比如: $('#tt').treegrid({ url:'get_data.php', idField:'id', ...
- android蓝牙主动发起配对实例
package cn.madfinger.core; import java.io.IOException; import java.lang.reflect.Method; import java. ...
- swift 数据存储
1.plist 存储 1.利用沙盒根目录拼接“Documents”字符串 //存储 func saveArray() { // 1.获得沙盒根路径,不管是真机还是模拟机,用它是最合适不过了 let h ...
- maven 配置Project Facets时further configuration available不出来问题
如果下边的 further configuration available不出来 把Dynamic web module 去掉勾选,应用与项目,然后再点开项目的properties,再选中Dynami ...
- IOS计算两点之间的距离
//广州经纬度 CLLocationCoordinate2D guangZhouLocation; guangZhouLocation.latitude = 23.20; guangZhouLocat ...