用的是.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的更多相关文章

  1. SignalR入门之多平台SignalR服务端

    之前创建SignalR服务端是基于Web应用程序而言的.那么能不能把SignalR服务端做成控制台应用程序.Winform或windows服务呢? 答案是肯定的. 之前尽管看起来好像是IIS和ASP. ...

  2. 创建自托管的SignalR服务端

    微软官方例子地址:http://www.asp.net/signalr/overview/deployment/tutorial-signalr-self-host 1.说明: SignalR服务端可 ...

  3. 记录一次SignalR服务端实现过程

    前言:最近手上一个项目需要后端实时推送数据到前端,第一个想到的就是微软的SignalR,由于之前都是平时没事写的Demo,没有用到实际项目中,这次恰好用到了,因此记录下来整个实现过程(网上也有很多类似 ...

  4. .net core signalR 服务端强制中断用户连接

    .net core signalR 服务端断开连接 { } { } *:first-child { } *:last-child { } { } { } { } { } { } { } { } { } ...

  5. WPF创建SignalR服务端(转)

    在网上看到了一个帖子,比较详细,博主写的很好. 地址:http://blog.csdn.net/lordwish/article/details/51786200

  6. signalr服务端-基础搭建

    signalr 支持 iis托管.winform.windowsservices.wpf 托管 这里我采用winfrom托管 首先画一个这样的窗体 在服务项目通过项目管理包安装signalr类库 安装 ...

  7. C#基于用户和角色的验证,服务端web 客户端wpf

    应用程序服务 <?xml version="1.0"?> <!--  For more information on how to configure your ...

  8. SignalR+NAudio实现语音会话[WPF]

    原文:SignalR+NAudio实现语音会话[WPF] 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lordwish/article/detai ...

  9. SignalR+AForge实现视频会话[WPF]

    原文:SignalR+AForge实现视频会话[WPF] 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lordwish/article/detai ...

  10. 在后台主机中托管SignalR服务并广播心跳包

    什么是后台主机 在之前的 Asp.NETCore 轻松学系列中,曾经介绍过一个轻量级服务主机 IHostedService ,利用 IHostedService 可以轻松的实现一个系统级别的后台服务, ...

随机推荐

  1. Powershell 调用cmd 运行exe、bat、jar文件

    1. 配置路径 $nginxPath = "C:\path\to\nginx" $redisPath = "C:\path\to\redis" $ruoyiAd ...

  2. NebKit简介及工作流程

    引言 随着云计算技术的不断发展,容器化技术已成为现代软件开发和部署的重要组成部分.NebKit作为一个创新的容器编排和管理工具,旨在简化这一过程,提高开发效率和系统的可靠性.本文将对NebKit进行简 ...

  3. Flink - [02] 安装部署(Standalone)

    一.准备 1.角色规划 Flink Standalone 角色规划 节点名称 node01 node02 node03 master ○     worker   ○ ○ zookeeper ○ ○ ...

  4. springboot2.1.6整合activiti6.0(二)--网页流程编辑器bpmnjs

    网页流程编辑器bpmnjs 官网:https://bpmn.io/ github:https://github.com/bpmn-io/bpmn-js-examples 因为还需要做一些改造,才能使其 ...

  5. pnpm:无法加载文件 C:\Users\Five\AppData\Roaming\npm\pnpm.ps1 ,因为在此系统上禁止运行脚本

    前言 重装完了电脑系统,运行pnpm 无法加载文件,pnpm -V也不行 解决方案 用管理员方式启动power shell 输入命令:set-ExecutionPolicy RemoteSigned ...

  6. 互联网寒冬下,如何写好一份.NET求职简历?附带简洁免费的简历模板!!!

    前言 在当今互联网行业的寒冬时期,每一位求职者都面临着更为激烈的竞争环境,如何在众多.NET候选人中脱颖而出,成为企业心仪的对象,用心准备一份简历显得尤为重要.简历不仅是个人职业经历的简要概述,更是向 ...

  7. 关于jsp的MySQL数据库连接问题

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  8. 对称&反对称&完全固定边界条件

    ABAQUS Boundary Condition XSYMM 对称边界条件,对称面为与坐标轴1垂直的平面,即U1=UR2=UR3=0; YSYMM 对称边界条件,对称面为与坐标轴2垂直的平面,即U2 ...

  9. Vulnhub-Hackme

    一.靶机搭建 选择扫描虚拟机 选择路径即可 二.信息收集 靶机信息 Name: hackme: 1 Date release: 18 Jul 2019 难度:初级,目标是通过web漏洞获得有限的权限访 ...

  10. golang单机锁实现

    1.锁的概念引入 首先,为什么需要锁? 在并发编程中,多个线程或进程可能同时访问和修改同一个共享资源(例如变量.数据结构.文件)等,若不引入合适的同步机制,会引发以下问题: 数据竞争:多个线程同时修改 ...