SignalR即时通讯 :WPF+Xamarin.Android

1、背景介绍

PDA操作物料出入库信息投送到大屏显示

2、WPF服务端

添加OWINMicrosoft.AspNet.SignalR.Core引用

2.1、创建启动类

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(CorsOptions.AllowAll);
        app.MapSignalR();
    }
}

2.2、创建Hub实现类

public class ServiceHub : Hub
{
    public void Send(string name, string message)
    {
        Clients.All.addMessage(name, message);
    }
    public override Task OnConnected()
    {
        Application.Current.Dispatcher.Invoke(() =>
            ((MainWindow)Application.Current.MainWindow).WriteToConsole("Client connected: " + Context.ConnectionId));
        return base.OnConnected();
    }
    public override Task OnDisconnected(bool ss)
    {
        Application.Current.Dispatcher.Invoke(() =>
            ((MainWindow)Application.Current.MainWindow).WriteToConsole("Client disconnected: " + Context.ConnectionId));
        return base.OnDisconnected(ss);
    }
}

2.3、启动、关闭服务

public partial class MainWindow : Window
{
    public IDisposable SignalR { get; set; }
    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()
    {
        string ServerURI = ConfigurationManager.AppSettings["serviceUri"];
        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");
    }
}

3、Xamarin发送端

引用 Microsoft.AspNet.SignalR.Client

public class SignalrChatClient
{
    private readonly HubConnection _connection;
    private readonly IHubProxy _proxy;//客户端代理服务器端中心
    public static SignalrChatClient CurrentClient;
    public static SignalrChatClient SignalrChatClientBuild(string serverIp)
    {
        if (CurrentClient == null)
        {
            CurrentClient = new SignalrChatClient(serverIp);
        }
        return CurrentClient;
    }

    private SignalrChatClient(string serverIp)
    {
        _connection = new HubConnection(serverIp);
        _proxy = _connection.CreateHubProxy("ServiceHub");
    }

    //负责连接的方法
    public async Task<string> Connect()
    {
        if (_connection != null)
        {
            if (_connection.State != ConnectionState.Connected)
            {
                try
                {
                    await _connection.Start();
                    return "Y";
                }
                catch
                {
                    return "SignalR服务连接失败+" + _connection.Url;
                }
            }
        }
        return "SignalR连接对象为空:" + _connection.Url;
    }

    //负责发送的方法
    public Task Send(string message)
    {
        string serverMethod = "Send";
        if (_connection != null)
        {
            if (_connection.State != ConnectionState.Connected)
            {
                return null;
            }
            if (_proxy != null)
            {
                return _proxy.Invoke(serverMethod, "test", message);
            }
        }
        return null;
    }
}

4、WPF大屏接收端

引用 Microsoft.AspNet.SignalR.Client

private async void ConnectAsync()
{
    string ServerURI = ConfigurationManager.AppSettings["serviceUri"];
    Connection = new HubConnection(ServerURI);
    Connection.Closed += Connection_Closed;
    HubProxy = Connection.CreateHubProxy("ServiceHub");
    HubProxy.On<string, string>("AddMessage", (name, message) =>
        //接收到数据后的处理逻辑
    );
    try
    {
        await Connection.Start();
    }
    catch (HttpRequestException)
    {
        StatusText.Content = "Unable to connect to server: Start server before connecting clients.";
        return;
    }
}

特别注意

  • 服务端、客户端SignalR版本需要保持一致,否则无法连接
  • 相应端口需要开放,否则无法连接
posted @ 2022-10-29 17:12  HKBlog  阅读(67)  评论(0编辑  收藏  举报