[SignalR Learning Series] 5. SignalR WPF program, signalrwpf

Source: Internet
Author: User

[SignalR Learning Series] 5. SignalR WPF program, signalrwpf

First, create a WPF Server and create a WPF project.

Install the Nuget package

Replace MainWindows's Xaml code

<Window x:Class="WPFServer.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="WPF SignalR Server" Height="319" Width="343  ">    <Grid>        <Button x:Name="ButtonStart" Content="Start" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="100" Click="ButtonStart_Click"/>        <Button x:Name="ButtonStop" Content="Stop" HorizontalAlignment="Left" Margin="225,10,0,0" VerticalAlignment="Top" Width="100" Click="ButtonStop_Click" IsEnabled="False"/>        <RichTextBox x:Name="RichTextBoxConsole" HorizontalAlignment="Left" Height="243" Margin="10,35,0,0" VerticalAlignment="Top" Width="315">            <FlowDocument>                <Paragraph>                </Paragraph>            </FlowDocument>        </RichTextBox>    </Grid></Window>

Replacing MainWindows background code

using Microsoft.AspNet.SignalR;using Microsoft.Owin.Cors;using Microsoft.Owin.Hosting;using Owin;using System;using System.Reflection;using System.Threading.Tasks;using System.Windows;namespace WPFServer{    /// <summary>    /// WPF host for a SignalR server. The host can stop and start the SignalR    /// server, report errors when trying to start the server on a URI where a    /// server is already being hosted, and monitor when clients connect and disconnect.     /// The hub used in this server is a simple echo service, and has the same     /// functionality as the other hubs in the SignalR Getting Started tutorials.    /// For simplicity, MVVM will not be used for this sample.    /// </summary>    public partial class MainWindow : Window    {        public IDisposable SignalR { get; set; }        const string ServerURI = "http://localhost:8080";        public MainWindow()        {            InitializeComponent();        }        /// <summary>        /// Calls the StartServer method with Task.Run to not        /// block the UI thread.         /// </summary>        private void ButtonStart_Click(object sender, RoutedEventArgs e)        {            WriteToConsole("Starting server...");            ButtonStart.IsEnabled = false;            Task.Run(() => StartServer());        }        /// <summary>        /// Stops the server and closes the form. Restart functionality omitted        /// for clarity.        /// </summary>        private void ButtonStop_Click(object sender, RoutedEventArgs e)        {            SignalR.Dispose();            Close();        }        /// <summary>        /// Starts the server and checks for error thrown when another server is already         /// running. This method is called asynchronously from Button_Start.        /// </summary>        private void StartServer()        {            try            {                SignalR = WebApp.Start(ServerURI);            }            catch (TargetInvocationException)            {                WriteToConsole("A server is already running at " + ServerURI);                this.Dispatcher.Invoke(() => ButtonStart.IsEnabled = true);                return;            }            this.Dispatcher.Invoke(() => ButtonStop.IsEnabled = true);            WriteToConsole("Server started at " + ServerURI);        }        ///This method adds a line to the RichTextBoxConsole control, using Dispatcher.Invoke if used        /// from a SignalR hub thread rather than the UI thread.        public void WriteToConsole(String message)        {            if (!(RichTextBoxConsole.CheckAccess()))            {                this.Dispatcher.Invoke(() =>                    WriteToConsole(message)                );                return;            }            RichTextBoxConsole.AppendText(message + "\r");        }    }    /// <summary>    /// Used by OWIN's startup process.     /// </summary>    class Startup    {        public void Configuration(IAppBuilder app)        {            app.UseCors(CorsOptions.AllowAll);            app.MapSignalR();        }    }    /// <summary>    /// Echoes messages sent using the Send message by calling the    /// addMessage method on the client. Also reports to the console    /// when clients connect and disconnect.    /// </summary>    public class MyHub : Hub    {        public void Send(string name, string message)        {            Clients.All.addMessage(name, message);            //Groups.Add        }        public override Task OnConnected()        {            //Use Application.Current.Dispatcher to access UI thread from outside the MainWindow class            Application.Current.Dispatcher.Invoke(() =>                ((MainWindow)Application.Current.MainWindow).WriteToConsole("Client connected: " + Context.ConnectionId));            return base.OnConnected();        }        public override Task OnDisconnected(bool ss)        {            //Use Application.Current.Dispatcher to access UI thread from outside the MainWindow class            Application.Current.Dispatcher.Invoke(() =>                ((MainWindow)Application.Current.MainWindow).WriteToConsole("Client disconnected: " + Context.ConnectionId));            return base.OnDisconnected(ss);        }    }}

 

Create a WPF Client and create a WPF Project

 

Install the Nuget package

 

Replace the front-end xmal file of MainWindow

<Window x:Name="WPFClient" x:Class="WPFClient.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="WPF SignalR Client" Height="552" Width="517" MinWidth="517" MinHeight="552" ResizeMode="CanMinimize" Closing="WPFClient_Closing">    <Grid>        <StackPanel x:Name="SignInPanel" Margin="10,0" MaxWidth="550">            <Label Content="Enter user name:"/>            <Grid>                <TextBox x:Name="UserNameTextBox" Height="20" Margin="0,0,80,0"/>                <Button x:Name="SignInButton" Content="Sign In" Width="75" Click="SignInButton_Click" HorizontalAlignment="Right"/>            </Grid>            <Label x:Name="StatusText" Visibility="Collapsed" HorizontalAlignment="Center" Margin="0,10"/>        </StackPanel>        <StackPanel x:Name="ChatPanel" Margin="10" MaxWidth="550" Visibility="Collapsed">            <Grid>                <TextBox x:Name="TextBoxMessage" Height="20" TextWrapping="Wrap" Margin="0,0,80,0"/>                <Button x:Name="ButtonSend" Content="Send" Width="75" Height="20" Click="ButtonSend_Click" IsDefault="True" IsEnabled="False" HorizontalAlignment="Right"/>            </Grid>            <RichTextBox x:Name="RichTextBoxConsole" HorizontalAlignment="Left" Height="461" ScrollViewer.VerticalScrollBarVisibility="Auto" Margin="0,10" IsReadOnly="True"/>        </StackPanel>    </Grid></Window>

Replace background code

using System;using System.Net.Http;using System.Windows;using Microsoft.AspNet.SignalR.Client;namespace WPFClient{    /// <summary>    /// SignalR client hosted in a WPF application. The client    /// lets the user pick a user name, connect to the server asynchronously    /// to not block the UI thread, and send chat messages to all connected     /// clients whether they are hosted in WinForms, WPF, or a web application.    /// For simplicity, MVVM will not be used for this sample.    /// </summary>    public partial class MainWindow : Window    {        /// <summary>        /// This name is simply added to sent messages to identify the user; this         /// sample does not include authentication.        /// </summary>        public String UserName { get; set; }        public IHubProxy HubProxy { get; set; }        const string ServerURI = "http://localhost:8080/signalr";        public HubConnection Connection { get; set; }        public MainWindow()        {            InitializeComponent();        }        private void ButtonSend_Click(object sender, RoutedEventArgs e)        {            HubProxy.Invoke("Send", UserName, TextBoxMessage.Text);            TextBoxMessage.Text = String.Empty;            TextBoxMessage.Focus();        }        /// <summary>        /// Creates and connects the hub connection and hub proxy. This method        /// is called asynchronously from SignInButton_Click.        /// </summary>        private async void ConnectAsync()        {            Connection = new HubConnection(ServerURI);            Connection.Closed += Connection_Closed;            HubProxy = Connection.CreateHubProxy("MyHub");            //Handle incoming event from server: use Invoke to write to console from SignalR's thread            HubProxy.On<string, string>("AddMessage", (name, message) =>                this.Dispatcher.Invoke(() =>                    RichTextBoxConsole.AppendText(String.Format("{0}: {1}\r", name, message))                )            );            try            {                await Connection.Start();            }            catch (HttpRequestException)            {                StatusText.Content = "Unable to connect to server: Start server before connecting clients.";                //No connection: Don't enable Send button or show chat UI                return;            }            //Show chat UI; hide login UI            SignInPanel.Visibility = Visibility.Collapsed;            ChatPanel.Visibility = Visibility.Visible;            ButtonSend.IsEnabled = true;            TextBoxMessage.Focus();            RichTextBoxConsole.AppendText("Connected to server at " + ServerURI + "\r");        }        /// <summary>        /// If the server is stopped, the connection will time out after 30 seconds (default), and the         /// Closed event will fire.        /// </summary>        void Connection_Closed()        {            //Hide chat UI; show login UI            var dispatcher = Application.Current.Dispatcher;            dispatcher.Invoke(() => ChatPanel.Visibility = Visibility.Collapsed);            dispatcher.Invoke(() => ButtonSend.IsEnabled = false);            dispatcher.Invoke(() => StatusText.Content = "You have been disconnected.");            dispatcher.Invoke(() => SignInPanel.Visibility = Visibility.Visible);        }        private void SignInButton_Click(object sender, RoutedEventArgs e)        {            UserName = UserNameTextBox.Text;            //Connect to server (use async method to avoid blocking UI thread)            if (!String.IsNullOrEmpty(UserName))            {                StatusText.Visibility = Visibility.Visible;                StatusText.Content = "Connecting to server...";                ConnectAsync();            }        }        private void WPFClient_Closing(object sender, System.ComponentModel.CancelEventArgs e)        {            if (Connection != null)            {                Connection.Stop();                Connection.Dispose();            }        }    }}

 

In the solution properties, set the Server and Client to start together.

View running results

 

Source code link:

Link: http://pan.baidu.com/s/1eRC2qVw password: twh3

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.