.net core using real-time communication SignalR

These days in the study SignalR, most of the examples are online chat rooms, my demand is to send information to the service side of the front display. And requires the user to achieve a single push.

User login I use ClaimsIdentity, will not explain here, if not quite understand, you can see this article https://www.cnblogs.com/zhangjd/p/11332558.html

Recommended https://www.cnblogs.com/laozhang-is-phi/p/netcore-vue-signalr.html#tbCommentBody this blog, written in great detail, and with Dome

First, the back-end implementation

1, reference SignalR package

Install-Package Microsoft.AspNetCore.SignalR

2, a class declaration record the connection information to the user.

1     public class SignalRModel
2     {
3         public static Dictionary<string, SignalRStatus> StaticList = new Dictionary<string, SignalRStatus>();
4         public static Dictionary<string, string> SignalRList { get; set; } = new Dictionary<string, string>();
5     }

3, the statement Hub, where I rewrote connect and disconnect methods used to bind users and ConnectionId connections. (This is more complicated, because the third-party program to perform my program, you need to log real-time output of the currently executing program, but calls can not be directly written to perform in the controller, so I can not call to get the current user's login Id then I'll initiate a connection and disconnection method to deal with.)

 1 public class ChatHub : Hub
 2     {
 3         /// <summary>
 4         /// 连接成功
 5         /// </summary>
 6         /// <returns></returns>
 7         public override Task OnConnectedAsync()
 8         {
 9             var id = this.Context.ConnectionId;
10             var claimNameIdentifier = this.Context.User.Claims.FirstOrDefault(s => s.Type == ClaimTypes.NameIdentifier)?.Value;
11             SignalRModel.SignalRList.Add(id, claimNameIdentifier);
12             if (SignalRModel.StaticList.Any(s => s.Key.Equals(claimNameIdentifier)))
13             {
14                 SignalRModel.StaticList.Remove(claimNameIdentifier);
15             }
16             SignalRModel.StaticList.Add(claimNameIdentifier, SignalRStatus.Open);
17             return base.OnConnectedAsync();
18         }
19         /// <summary>
20         /// 断开连接
21         /// </summary>
22         public override Task OnDisconnectedAsync(Exception exception)
23         {
24             var id = this.Context.ConnectionId;
25             var claimNameIdentifier = this.Context.User.Claims.FirstOrDefault(s => s.Type == ClaimTypes.NameIdentifier)?.Value;
26             SignalRModel.SignalRList.Remove(id);
27             SignalRModel.StaticList.Remove(claimNameIdentifier);
28             return base.OnDisconnectedAsync(exception);
29         }
30         /// <summary>
31         /// 发送消息
32         /// </summary>
33         /// <param name="user"></param>
34         /// <param name="message"></param>
35         /// <returns></returns>
36         public async Task SendMessage(string user, string message)
37         {
38             await Clients.All.SendAsync("ReceiveMessage", user, message);
39         }
40     }

4, when the program starts, the user is connected to the recording of such information, as a single injection embodiment, the user and the corresponding relationship stored in the connection, convenient single communication.

1   services.AddSingleton<SignalRModel>(provider =>
2   {
3       return new SignalRModel();
4   });

5, configuration

 1), was added in the ConfigureServices

services.AddSignalR (); // write in addmvc () in front 
. services.AddMvc () SetCompatibilityVersion (CompatibilityVersion.Version_2_2) ;

 2), was added in the Configure

app.UseMvc (); 
app.UseSignalR (routes => { routes.MapHub <ChatHub> ( " / API / chatHub " ); }); // write back UseMvc

6, I wrote here two back-end interfaces to send messages, except that the first one is the mass, the second is sent for a connection.

. 1          [HttpGet ( " SendAll " )]
 2          public IActionResult SendAll ()
 . 3          {
 . 4              _hubContext.Clients.All.SendAsync ( " receiveUpdate " , " push all people " ) .Wait ();
 . 5              return Ok ( " push all people ." );
 . 6          }
 . 7          [HttpGet ( " SendOnly " )]
 . 8          public IActionResult SendOnly ()
 . 9          {
 10              var claimNameIdentifier = User.Claims.FirstOrDefault(s => s.Type == ClaimTypes.NameIdentifier)?.Value;
11             if (string.IsNullOrEmpty(claimNameIdentifier))
12             {
13                 return Ok(new { code = ResultCode.NotLogin, message = "用户未登陆!" });
14             }
15             _hubContext.Clients.Clients(claimNameIdentifier).SendAsync("ReceiveUpdate", DateTime.Now).Wait();
16             return Ok("推送当前登录用户");
17         }

7, I used the actual project like this, send log messages to the user currently logged on to determine whether the connection is disconnected, and then need to get off if written in front of the log is sent to the front, the status of the connection into a connection, send it back to normal.

 1    foreach (var item in SignalRModel.SignalRList.Where(s => s.Value.Equals(userId.ToString())).ToList())
 2    {
 3       if (SignalRModel.StaticList.Any(s => s.Key.Equals(userId.ToString()) && s.Value == SignalRStatus.Open))
 4       {
 5          if (SignalRModel.StaticList.Any(s => s.Key.Equals(userId.ToString())))
 6          {
 7               SignalRModel.StaticList.Remove(userId.ToString());
 8          }
 9          SignalRModel.StaticList.Add(userId.ToString(), SignalRStatus.working);
10          _hubContext.Clients.Client(item.Key).SendAsync("ReceiveUpdate", FileHelper.ReadFile(Path.Combine(filePath, "tls_simplify.txt"), Encoding.UTF8)).Wait();
11       }
12       _hubContext.Clients.Client(item.Key).SendAsync("ReceiveUpdate", args.Data).Wait();
13    }

Second, the front vue

1, the installation dependencies

npm install @aspnet/signalr

2, sample page

  1 <template>
  2     <section>
  3         <div style="display: none1">
  4             <el-form ref="form" label-width="80px" @submit.prevent="onSubmit"
  5                      style="margin:20px;width:60%;min-width:600px;">
  6                 <el-form-item label="用户名">
  7                     <el-input v-model="userName"></el-input>
  8                 </el-form-item>
  9                 <el-form-item label="密码">
 10                     <el-input v-model="userMessage"></el-input>
 11                 </el-form-item>
 12             </el-form>
 13             <ul v-for="(item, index) in messages" v-bind:key="index + 'itemMessage'">
 14                 <li><b>Name: </b>{{item.user}}</li>
 15                 <li><b>Message: </b>{{item.message}}</li>
 16             </ul>
 17             <p>
 18             <b>后台发送消息: </b>{{this.postMessage}}
 19             </p>
 20             <el-button type="primary" @click="submitCard">登录</el-button>
 21             <el-button type="primary" @click="getLogs">查询</el-button>
 22         </div>
 23     </section>
 24 </template>
 25 
 26 <script>
 27    
 28     import * as signalR from "@aspnet/signalr";
 29 
 30     export default {
 31       name: 'Dashboard',
 32         data() {
 33             return {
 34                 filters: {
 35                     LinkUrl: ''
 36                 },
 37                 listLoading: true,
 38                 postMessage: "",
 39                 userName: "Tom",
 40                 userMessage: "123",
 41                 connection: "",
 42                 messages: [],
 43                 t: ""
 44 
 45             }
 46         },
 47         methods: {
 48             getRoles() {
 49                 let thisvue=this;
 50                 let para = {
 51                     page: this.page,
 52                     key: this.filters.LinkUrl
 53                 };
 54                 this.listLoading = true;
 55                 thisvue.connection.start().then(() => {
 56                    thisvue.connection.invoke('GetLatestCount', 1).catch(function (err) {
 57                    return console.error(err);
 58                 });
 59             });
 60             },
 61             submitCard: function () {
 62                 if (this.userName && this.userMessage) {
 63                     this.connection.invoke('SendMessage', this.userName, this.userMessage).catch(function (err) {
 64                         return console.error(err);
 65                     });
 66 
 67                 }
 68             },
 69             getLogs: function () {
 70                 this.listLoading = true;
 71                 this.connection.invoke('GetLatestCount', 1).catch(function (err) {
 72                     return console.error(err);
 73                 });
 74             }
 75         },
 76         created: function () {
 77             let thisVue = this;
 78             thisVue.connection = new signalR.HubConnectionBuilder()
 79                 .withUrl('http://localhost:5000/api/chatHub')
 80                 .configureLogging(signalR.LogLevel.Information)
 81                 .build();
 82             thisVue.connection.on('ReceiveMessage', function (user, message) {
 83                 thisVue.messages.push({user, message});
 84             });
 85 
 86             thisVue.connection.on('ReceiveUpdate', function (update) {
 87                 console.info('update success!')
 88                 thisVue.listLoading = false;
 89                 thisVue.postMessage = update;
 90                 window.clearInterval(this.t)
 91             })
 92         },
 93         mounted() {
 94             this.getRoles();
 95         },
 96         beforeDestroy() {
 97             window.clearInterval(this.t)
 98             this.connection.stop();
 99         }
100     }
101 </script>
102 
103 <style scoped>
104     .demo-table-expand {
105         font-size: 0;
106     }
107 
108     .demo-table-expand label {
109         width: 90px;
110         color: #99a9bf;
111     }
112 
113     .demo-table-expand .el-form-item {
114         margin-right: 0;
115         margin-bottom: 0;
116         width: 30%;
117     }
118 
119     .EXC {
120         color: red;
121     }
122 </style>

 

Guess you like

Origin www.cnblogs.com/zhangjd/p/11332849.html