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!!
#####
愿你一寸一寸地攻城略地,一点一点地焕然一新
#####