SignalR服务端嵌入到WPF
用的是.net framework 4.7.2的WPF。
<Window x:Class="EBServerTry.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:EBServerTry"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0">
<Button x:Name="stBtn" Click="stBtn_Click" Height="30" Width="80" Content="启动"/>
<Button x:Name="stopBtn" Click="stopBtn_Click" Height="30" Width="80" Content="停止"/>
</WrapPanel>
<RichTextBox Grid.Row="1" Grid.RowSpan="2" Name="richText" VerticalScrollBarVisibility="Auto"/>
</Grid>
</Window>
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//Microsoft.Owin.Hosting
//Microsoft.Aspnet.SignalR
//Microsoft.Owin.Host.HttpListener
//Install-Package Microsoft.Owin.Cors[不需要]
namespace EBServerTry
{
/// <summary>
/// 客户端需要监听的方法
/// </summary>
public interface IEbTest
{
Task ReceiveMsg(string msg);
Task ReceiveAllClientNames(List<string> names);
}
/// <summary>
/// 服务端Hub
/// </summary>
public class EBTestHub : Hub<IEbTest>
{
/// <summary>
/// key->用户名,value->connectionId
/// </summary>
private static Dictionary<string, string> _connectDict = new Dictionary<string, string>();
private static Dictionary<string, List<string>> _groupInfoDict = new Dictionary<string, List<string>>();
public override Task OnConnected()
{
var a = Context.QueryString["username"];
if (a != null)
{
_connectDict[a] = Context.ConnectionId;
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
string username = _connectDict.FirstOrDefault(x => x.Value == Context.ConnectionId).Key;
if(username != null)
{
_connectDict.Remove(username);
}
return base.OnDisconnected(stopCalled);
}
public override Task OnReconnected()
{
return base.OnReconnected();
}
private void WriteToConsole(string msg)
{
//// 在 UI 线程上更新 UI
Application.Current.Dispatcher.Invoke(() =>
{
((MainWindow)Application.Current.MainWindow).WriteToConsole($"{msg}");
});
}
#region 客户端可调用的方法
public Task SendAllTest(string msg)
{
WriteToConsole($"该消息所有连接客户端可见:{msg}");
return Clients.All.ReceiveMsg($"该消息所有连接客户端可见:{msg}");
}
public Task SendOthersTest(string msg)
{
WriteToConsole($"该消息仅发送者不可见:{msg}");
return Clients.Others.ReceiveMsg($"该消息仅发送者不可见:{msg}");
}
public Task SendSelfTest(string msg)
{
WriteToConsole($"该消息仅发送者可见:{msg}");
return Clients.Caller.ReceiveMsg($"该消息仅发送者可见:{msg}");
}
public Task SendUserTest(string username, string msg)
{
string connectionId;
if (_connectDict.TryGetValue(username, out connectionId))
{
WriteToConsole($"收到来自{username}发送的消息:{msg}");
Clients.Client(connectionId).ReceiveMsg($"收到来自{username}发送的消息:{msg}");
}
return Task.CompletedTask;
}
public Task GetAllClientNames()
{
return Clients.Caller.ReceiveAllClientNames(_connectDict.Keys.ToList());
}
public async Task AddUserToGroup(string groupName)
{
await Groups.Add(Context.ConnectionId, groupName);
await Clients.Caller.ReceiveMsg($"当前用户已经被添加到集群{groupName}");
}
public async Task RemoveUserFromGroup(string groupName)
{
await Groups.Remove(Context.ConnectionId, groupName);
await Clients.Caller.ReceiveMsg($"当前用户已经被移除出集群{groupName}");
}
public async Task SendToGroup(string groupName, string msg)
{
await Clients.Group(groupName).ReceiveMsg($"集群{groupName}信息:{msg}");
}
#endregion
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public IDisposable SignalR { get; set; }
static string SerVerURI = "http://localhost:8080";//部署时候需要填上具体数字!!!!!
public MainWindow()
{
InitializeComponent();
StartServer();
}
private void StartServer()
{
try
{
SignalR = WebApp.Start(SerVerURI);
}
catch(Exception e)
{
WriteToConsole(e.Message);
return;
}
WriteToConsole($"服务正在运行...{SerVerURI}");
}
public void WriteToConsole(string msg)
{
Dispatcher.Invoke(() =>
{
string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
richText.AppendText($"[{timeStr}]:{msg} \r\n");
});
}
private void stBtn_Click(object sender, RoutedEventArgs e)
{
}
private void stopBtn_Click(object sender, RoutedEventArgs e)
{
}
}
}
跑在服务器上时候,需要做两件事:
(1)开放服务器的相应端口
(2)ServerUrl改为实际数字的IP地址,而不能是localhost!!
SignalR服务端嵌入到WPF的更多相关文章
- SignalR入门之多平台SignalR服务端
之前创建SignalR服务端是基于Web应用程序而言的.那么能不能把SignalR服务端做成控制台应用程序.Winform或windows服务呢? 答案是肯定的. 之前尽管看起来好像是IIS和ASP. ...
- 创建自托管的SignalR服务端
微软官方例子地址:http://www.asp.net/signalr/overview/deployment/tutorial-signalr-self-host 1.说明: SignalR服务端可 ...
- 记录一次SignalR服务端实现过程
前言:最近手上一个项目需要后端实时推送数据到前端,第一个想到的就是微软的SignalR,由于之前都是平时没事写的Demo,没有用到实际项目中,这次恰好用到了,因此记录下来整个实现过程(网上也有很多类似 ...
- .net core signalR 服务端强制中断用户连接
.net core signalR 服务端断开连接 { } { } *:first-child { } *:last-child { } { } { } { } { } { } { } { } { } ...
- WPF创建SignalR服务端(转)
在网上看到了一个帖子,比较详细,博主写的很好. 地址:http://blog.csdn.net/lordwish/article/details/51786200
- signalr服务端-基础搭建
signalr 支持 iis托管.winform.windowsservices.wpf 托管 这里我采用winfrom托管 首先画一个这样的窗体 在服务项目通过项目管理包安装signalr类库 安装 ...
- C#基于用户和角色的验证,服务端web 客户端wpf
应用程序服务 <?xml version="1.0"?> <!-- For more information on how to configure your ...
- SignalR+NAudio实现语音会话[WPF]
原文:SignalR+NAudio实现语音会话[WPF] 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lordwish/article/detai ...
- SignalR+AForge实现视频会话[WPF]
原文:SignalR+AForge实现视频会话[WPF] 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lordwish/article/detai ...
- 在后台主机中托管SignalR服务并广播心跳包
什么是后台主机 在之前的 Asp.NETCore 轻松学系列中,曾经介绍过一个轻量级服务主机 IHostedService ,利用 IHostedService 可以轻松的实现一个系统级别的后台服务, ...
随机推荐
- C#(面向对象的托管语言)类库(区别于应用程序)的异常处理思路
1.不要做出任何应用程序才需要考虑抉择策略,不能想当然的决定一些错误情形.具体的一个体现形式是什么异常都捕获.这不是类库的职责,因为无法掌握所有的调用者的使用情形,这些不确定性是委托.虚方法.接口等特 ...
- Visual Studio 好用的主题+字体推荐!!!
Vs2022主题+字体 Visual Studio(VS)是一款功能强大的集成开发环境(IDE),可以用于开发各种类型的应用程序,包括桌面应用.Web应用.移动应用等.它提供了许多主题设置和字体选项, ...
- 对称&反对称&完全固定边界条件
ABAQUS Boundary Condition XSYMM 对称边界条件,对称面为与坐标轴1垂直的平面,即U1=UR2=UR3=0; YSYMM 对称边界条件,对称面为与坐标轴2垂直的平面,即U2 ...
- postman 如何比较两台电脑的脚本是否一样
- Vulnhub-sundown
总结:该靶机是一个wordpress管理系统,需要信息收集得到插件信息,然后搜索插件漏洞,得到一个文件包含exp,利用其得到一个普通用户,利用hydra爆破密码然后ssh连接,信息收集得到一个数据库配 ...
- 【独立开发作品】SlideBrowser 一个轻量的滑动浏览器,给你不一样的交互体验
产品介绍 SlideBrowser是一个滑动浏览器,当你鼠标移动到屏幕边缘,自动出现,当失焦时自动隐藏. 使用场景 在应用全屏模式下查询资料.问 GPT 等 记录一些待办事项或者笔记 查看股市.币市信 ...
- mac zsh终端 goframe gf 别名冲突
前言 如果你使用的是 zsh 终端,可能会存在 gf 别名冲突( git fetch 快捷指令) 解决 终端运行 alias gf=gf,gf 工具会自动修改 .zshrc 中的别名设置,source ...
- protected修饰符讲解、java中继承的特点-java se进阶 day01
1.protected权限修饰符的介绍 之前在说权限修饰符时候,没有细说protected,今天,我们就来聊聊protected 如图,protected修饰符中,"不同包的子类" ...
- Warning MVC1000
场景重现 视图文件中有些代码如下: @Html.Partial("_Footer") 会出现警告: // 警告 MVC1000 Use of IHtmlHelper.Partial ...
- datasnap的Restful的接口方法
//Restful接口测试 //GET function Test(Value: string): string; //POST function updateTest(Value: string; ...