Search code examples
.netasp.net-mvcdeploymentsignalrsignalr-hub

Signalr:Connect to remote host through wpf


I have made a console application which works as a host for signal r and listens to port 8089.When I run wpf application and run that host application on localhost,every thing works fine.Now I have deployed that console application on server.Now when I try to connect ,it doesn't connect through wpf. So then I read that it supports only HTTP protocol and after reading that I made an website which connects to the server on remote server and it is connected successfully. My question is that is there any way I can connect to that server using wpf.I want to make a desktop chat application in which all clients will connect to same server so that it can broadcast.Any help will e appreciated

StartUp.CS

     public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Branch the pipeline here for requests that start with "/signalr"
                app.Map("/signalr", map =>
                {
                    // Setup the CORS middleware to run before SignalR.
                    // By default this will allow all origins. You can 
                    // configure the set of origins and/or http verbs by
                    // providing a cors options with a different policy.
                    map.UseCors(CorsOptions.AllowAll);
                    var hubConfiguration = new HubConfiguration
                    {
                        // You can enable JSONP by uncommenting line below.
                        // JSONP requests are insecure but some older browsers (and some
                        // versions of IE) require JSONP to work cross domain
                        // EnableJSONP = true
                    };
                    // Run the SignalR pipeline. We're not using MapSignalR
                    // since this branch already runs under the "/signalr"
                    // path.

                    hubConfiguration.EnableDetailedErrors = true;
                    map.RunSignalR(hubConfiguration);
                });
            }
        }


**Program.CS**


     class Program
        {
            static void Main(string[] args)
            {
                // This will *ONLY* bind to localhost, if you want to bind to all addresses
                // use http://*:8080 to bind to all addresses. 
                // See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx 
                // for more information.
                string url = "http://MyIpAddressOfServer:8089";
                using (WebApp.Start(url))
                {
                    Console.WriteLine("Server running on {0}", url);

                    Console.ReadLine();
                }
            }
        }

**MainWindowXaml.cs**

 public partial class MainWindow : Window
    {
        public System.Threading.Thread Thread { get; set; }
        public string Host = "http://MyIpAddressOfServer:8089/signalr";

        public IHubProxy Proxy { get; set; }
        public HubConnection Connection { get; set; }

        public bool Active { get; set; }

        public MainWindow()
        {
            InitializeComponent();
        }

        private async void ActionSendButtonClick(object sender, RoutedEventArgs e)
        {
            await SendMessage();
        }

        private async Task SendMessage()
        {
            await Proxy.Invoke("Addmessage", ClientNameTextBox.Text , MessageTextBox.Text);
        }
        private async void ActionWindowLoaded(object sender, RoutedEventArgs e)
        {
            Active = true;
            Thread = new System.Threading.Thread(() =>
            {
                Connection = new HubConnection(Host);
                Proxy = Connection.CreateHubProxy("MyHub");
                Proxy.On<string, string>("addmessage", (name, message) => OnSendData(name + ": " + message ));
                Connection.Start();

                while (Active)
                {
                    System.Threading.Thread.Sleep(10);
                }
            }) { IsBackground = true };
            Thread.Start();

        }

        private void OnSendData(string message)
        {
            try
            {
                Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => MessagesListBox.Items.Insert(0, message)));
            }
            catch (Exception e)
            {
            }
        }

        private async void ActionMessageTextBoxOnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter || e.Key == Key.Return)
            {
                await SendMessage();
                MessageTextBox.Text = "";
            }
        }
    }

Solution

  • Hi there are a few answers,

    Here is a MS example https://code.msdn.microsoft.com/windowsdesktop/Using-SignalR-in-WinForms-f1ec847b

    here is another example more on wpf http://damienbod.wordpress.com/2013/11/20/signalr-a-complete-wpf-client-using-mvvm/

    while the first link says winforms, it covers wpf as well.

    In case the link goes down, you want to use this nugget package Microsoft.AspNet.SignalR.Client

    The above package supports This package supports WinRT, Silverlight, WPF, console application, and Windows Phone clients, for both .NET 4 and .NET 4.5.

    You can find more info about that nugget package at this link http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-net-client

    public partial class MainWindow : Window
    {
        public System.Threading.Thread Thread { get; set; }
        public string Host = "http://x.x.x.x:8089/";
    
        public IHubProxy Proxy { get; set; }
        public HubConnection Connection { get; set; }
    
        public bool Active { get; set; }
    
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private async void ActionHeartbeatButtonClick(object sender, RoutedEventArgs e)
        {
            await SendHeartbeat();
        }
    
        private async void ActionSendButtonClick(object sender, RoutedEventArgs e)
        {
            await SendMessage();
        }
    
        private async void ActionSendObjectButtonClick(object sender, RoutedEventArgs e)
        {
            await SendHelloObject();
        }
    
        private async Task SendMessage()
        {
            await Proxy.Invoke("Addmessage", ClientNameTextBox.Text, MessageTextBox.Text);
        }
    
        private async Task SendHeartbeat()
        {
            await Proxy.Invoke("Heartbeat");
        }
    
        private async Task SendHelloObject()
        {
            HelloModel hello = new HelloModel { Age = Convert.ToInt32(HelloTextBox.Text), Molly = HelloMollyTextBox.Text };
            await Proxy.Invoke("sendHelloObject", hello);
        }
    
        private async void ActionWindowLoaded(object sender, RoutedEventArgs e)
        {
            Active = true;
            Thread = new System.Threading.Thread(() =>
            {
                Connection = new HubConnection(Host);
                Proxy = Connection.CreateHubProxy("MyHub");
    
                Proxy.On<string, string>("addmessage", (name, message) => OnSendData("Recieved addMessage: " + name + ": " + message));
                Proxy.On("heartbeat", () => OnSendData("Recieved heartbeat"));
                Proxy.On<HelloModel>("sendHelloObject", hello => OnSendData("Recieved sendHelloObject " + hello.Molly + " " + hello.Age));
    
                Connection.Start();
    
                while (Active)
                {
                    System.Threading.Thread.Sleep(10);
                }
            }) { IsBackground = true };
            Thread.Start();
    
        }
    
        private void OnSendData(string message)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => MessagesListBox.Items.Insert(0, message)));
        }
    
        private async void ActionMessageTextBoxOnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter || e.Key == Key.Return)
            {
                await SendMessage();
                MessageTextBox.Text = "";
            }
        }
    
    }
    
    
    
    <Window x:Class="SignalRTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Loaded="ActionWindowLoaded"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition Width="Auto"
                              MinWidth="149" />
        </Grid.ColumnDefinitions>
    
        <Label Content="Message:"
               Grid.Column="0"
               Grid.Row="0"
               Margin="5" />
        <TextBox Width="Auto"
                 Grid.Column="1"
                 Grid.Row="0"
                 Margin="5,5,10,5"
                 x:Name="ClientNameTextBox" />
        <TextBox Width="Auto"
                 Grid.Column="2"
                 Grid.Row="0"
                 Margin="5,5,10,5"
                 x:Name="MessageTextBox"
                 KeyDown="ActionMessageTextBoxOnKeyDown" />
        <Button Content="AddMessage"
                Grid.Column="3"
                Grid.Row="0"
                Margin="17,5"
                x:Name="SendButton"
                Click="ActionSendButtonClick" />
    
        <Label Content="Heartbeat:"
               Grid.Column="0"
               Grid.Row="1"
               Margin="5" />
        <Button Content="Send Heartbeat"
                Grid.Column="3"
                Grid.Row="1"
                Margin="17,5"
                x:Name="HeartbeatButton"
                Click="ActionHeartbeatButtonClick" />
    
        <Label Content="Age, Molly:"
               Grid.Column="0"
               Grid.Row="2"
               Margin="5" />
        <TextBox Width="Auto"
                 Grid.Column="1"
                 Grid.Row="2"
                 Margin="5,5,10,5"
                 x:Name="HelloTextBox" />
        <TextBox Width="Auto"
                 Grid.Column="2"
                 Grid.Row="2"
                 Margin="5,5,10,5"
                 x:Name="HelloMollyTextBox"
                 KeyDown="ActionMessageTextBoxOnKeyDown" />
        <Button Content="Send Object"
                Grid.Column="3"
                Grid.Row="2"
                Margin="17,5"
                x:Name="HelloButton"
                Click="ActionSendObjectButtonClick" />
    
        <ListBox Grid.Column="0"
                 Grid.Row="3"
                 Grid.ColumnSpan="4"
                 Margin="5"
                 x:Name="MessagesListBox" />
    </Grid>
    

    public class HelloModel
    {
        public string Molly { get; set; }
    
        public int Age { get; set; }
    
    }