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!!

posted @ 2024-04-26 13:25  JohnYang819  阅读(53)  评论(0编辑  收藏  举报