zoukankan      html  css  js  c++  java
  • Asp.Net Core API 和 WinForm 的 SignalR 例子

    什么是 SignalR?

    ASP.NET Core SignalR 是一个开源库,它简化了向应用程序添加实时 web 功能的功能。 实时 Web 功能使服务器端代码能够即时将内容推送到客户端。
    官方列举的SignalR适用场景:

    • 需要从服务器进行高频率更新的应用。 示例包括游戏、社交网络、投票、拍卖、地图和 GPS 应用。
    • 仪表板和监视应用。 示例包括公司仪表板、即时销售更新或旅行警报。
    • 协作应用。 协作应用的示例包括白板应用和团队会议软件。
    • 需要通知的应用。 社交网络、电子邮件、聊天、游戏、旅行警报和很多其他应用都需使用通知。

    创建SignalR服务端Asp.Net Core API 这参考了Blog系统的写法
    引用SignalR序列化的包
    Install-Package Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson -Version 3.1.3
    Startup类ConfigureServices方法里注册SignalR服务
    services.AddSignalR().AddNewtonsoftJsonProtocol();
    创建SignalR的Hub定义消息,分别是IChatClient和ChatHub
    IChatClient

      public interface IChatClient
      {
          /// <summary>
          /// SignalR接收信息
          /// </summary>
          /// <param name="message">信息内容</param>
          /// <returns></returns>
          Task ReceiveMessage(object message);
    
          /// <summary>
          /// SignalR接收信息
          /// </summary>
          /// <param name="user">指定接收客户端</param>
          /// <param name="message">信息内容</param>
          /// <returns></returns>
          Task ReceiveMessage(string user, string message);
    
          Task ReceiveUpdate(object message);
      }
    

    ChatHub

      public class ChatHub : Hub<IChatClient>
      {
          /// <summary>
          /// 向指定群组发送信息
          /// </summary>
          /// <param name="groupName">组名</param>
          /// <param name="message">信息内容</param>
          /// <returns></returns>
          public async Task SendMessageToGroupAsync(string groupName, string message)
          {
              await Clients.Group(groupName).ReceiveMessage(message);
          }
    
          /// <summary>
          /// 加入指定组
          /// </summary>
          /// <param name="groupName">组名</param>
          /// <returns></returns>
          public async Task AddToGroup(string groupName)
          {
              await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
          }
    
          /// <summary>
          /// 退出指定组
          /// </summary>
          /// <param name="groupName">组名</param>
          /// <returns></returns>
          public async Task RemoveFromGroup(string groupName)
          {
              await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
          }
    
          /// <summary>
          /// 向指定成员发送信息
          /// </summary>
          /// <param name="user">成员名</param>
          /// <param name="message">信息内容</param>
          /// <returns></returns>
          public async Task SendPrivateMessage(string user, string message)
          {
              await Clients.User(user).ReceiveMessage(message);
          }
    
          /// <summary>
          /// 当连接建立时运行
          /// </summary>
          /// <returns></returns>
          public override Task OnConnectedAsync()
          {
              //TODO..
              return base.OnConnectedAsync();
          }
    
          /// <summary>
          /// 当链接断开时运行
          /// </summary>
          /// <param name="ex"></param>
          /// <returns></returns>
          public override Task OnDisconnectedAsync(System.Exception ex)
          {
              //TODO..
              return base.OnDisconnectedAsync(ex);
          }
    
          public async Task SendMessage(string user, string message)
          {
              await Clients.All.ReceiveMessage(user, message);
          }
    
          //定于一个通讯管道,用来管理我们和客户端的连接
          //1、客户端调用 WinFormsApp,就像订阅
          //2、服务端主动向客户端发送数据,名字千万不能错
          //3、客户端再通过 ReceiveUpdate ,来接收
          public async Task WinFormsApp(string name, string msg)
          {
              await Clients.All.ReceiveUpdate($"接收到{name}的消息,消息内容:{msg}");
          }
      }
    

    创建中间件SignalRSendMildd和MiddlewareHelpers
    SignalRSendMildd

      /// <summary>
      /// 中间件
      /// </summary>
      public class SignalRSendMildd
      {
          /// <summary>
          ///上下文
          /// </summary>
          private readonly RequestDelegate _next;
    
          private readonly IHubContext<ChatHub> _hubContext;
    
          /// <summary>
          ///注入上下文
          /// </summary>
          /// <param name="next"></param>
          /// <param name="hubContext"></param>
          public SignalRSendMildd(RequestDelegate next, IHubContext<ChatHub> hubContext)
          {
              _next = next;
              _hubContext = hubContext;
          }
    
          /// <summary>
          /// SignalR过滤
          /// </summary>
          /// <param name="context"></param>
          /// <returns></returns>
          public async Task InvokeAsync(HttpContext context)
          {
              await _next(context);
          }
      }
    

    MiddlewareHelpers

      public static class MiddlewareHelpers
      {
          /// <summary>
          /// SignalR中间件
          /// </summary>
          /// <param name="app"></param>
          /// <returns></returns>
          public static IApplicationBuilder UseSignalRSendMildd(this IApplicationBuilder app)
          {
              return app.UseMiddleware<SignalRSendMildd>();
          }
      }
    

    Startup类Configure方法里调用中间件设置SignalR服务路由

         // signalr
             app.UseSignalRSendMildd();
             app.UseEndpoints(endpoints =>
             {
                 endpoints.MapControllers();
                 endpoints.MapHub<ChatHub>("/signalr/chatHub");
             });
    

    创建SignalR客户端发送消息返回发送的消息内容,这里客户端用winform
    这是界面

    引用SignalR的包
    Install-Package Microsoft.AspNetCore.SignalR.Client

          public partial class WinFormsApp : Form
      {
          private HubConnection connection;
    
          public WinFormsApp()
          {
              InitializeComponent();
              SignalRConnection();
          }
    
          public async void SignalRConnection()
          {
              connection = new HubConnectionBuilder()
                    .WithUrl("http://localhost:5000/signalr/chatHub")
                    .Build();
              await connection.StartAsync();
              connection.Closed += async (error) =>
              {
                  await Task.Delay(new Random().Next(0, 5) * 1000);
                  await connection.StartAsync();
              };
          }
    
          private async void button1_Click(object sender, EventArgs e)
          {
              try
              {
                  await connection.InvokeAsync("WinFormsApp", "SignalRClient", this.textBox1.Text);
                  connection.On<object>("ReceiveUpdate", (message) =>
                  {
                      this.Invoke(new Action(() =>
                      {
                          this.textBox2.Text = message.ToString();
                      }));
                  });
              }
              catch (Exception ex)
              {
                  this.textBox2.Text = ex.Message;
              }
          }
      }
    

    Demo下载

  • 相关阅读:
    CCF CSP 题解
    CCF CSP 2019032 二十四点
    CCF CSP 2018121 小明上学
    CCF CSP 2019092 小明种苹果(续)
    CCF CSP 2019091 小明种苹果
    CCF CSP 2019121 报数
    CCF CSP 2019031 小中大
    CCF CSP 2020061 线性分类器
    CCF CSP 2020062 稀疏向量
    利用国家气象局的webservice查询天气预报(转载)
  • 原文地址:https://www.cnblogs.com/SuperDust/p/12769647.html
Copyright © 2011-2022 走看看