vue +signalR 實現服務端到客戶端消息發送


系列

源碼地址:https://github.com/QQ2287991080/SignalRServerAndVueClientDemo

上一篇博客實現是了消息的實時通信,這一篇博客主要講如何從中心服務內部向客戶端發送消息。

先看下最終效果:

 

 

在core應用程序里加一個控制器TestController

注入控制器中的IHubContext實例,並且添加方法

    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        private readonly IHubContext<ChatHub> _hubContext;
        public TestController(IHubContext<ChatHub> hubContext)
        {
            _hubContext = hubContext;
        }
        [HttpGet]
        public async Task<int> Get()
        {
            await _hubContext.Clients.All.SendAsync("ReceiveMessage", "系統通知", $"北京時間{DateTime.Now}");
            return 0;
        }
    }

然后啟用路由和控制器

            //啟用控制器
            services.AddControllers();
          app.UseEndpoints(endpoints =>
            {
                //終結點設置路由默認
                endpoints.MapControllerRoute(
                               name: "default",
                               pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chathub");
            });

哎呀忘記配置跨域了

             //配置跨域
              services.AddCors(c =>
                c.AddPolicy("AllowAll", p =>
                {
                    p.AllowAnyOrigin();
                    p.AllowAnyMethod();
                    p.AllowAnyHeader();
                })
                );
            //配置跨域別把中間件的位置放錯了哦
            app.UseCors("AllowAll");

這里為啥要配置跨域呢,因為之前signalr的連接時連接客戶端的,它們基於底層的通信協議(這太高深了 ,俺也不懂),而現在我們通過瀏覽器發送請求獲取系統通知的話,就會存在跨域的情況,所以需要配置

因為現在需要發送請求,所以我安裝個axios

npm install axios

然后在mian.js配置下。

import axios from 'axios'
Vue.prototype.$http = axios

更新一下上次寫的home.vue里的代碼

<template>
  <div class="home">
    <h1>前端演示SignalR</h1>
    <input v-model="user" type="text" />
    <input v-model="message" type="text" />
    <button @click="sendAll">發送全部</button>
    <button @click="sendOwn">對自己發送</button>
    <button @click="sendClient">系統發送消息</button>

    <div>
      <ul v-for="(item ,index) in messages" v-bind:key="index +'itemMessage'">
        <li>{{item.user}} says {{item.message}}</li>
      </ul>
    </div>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
import * as signalR from "@aspnet/signalr";
export default {
  name: "Home",
  components: {
    HelloWorld
  },
  data() {
    return {
      user: "", //用戶
      message: "", //消息
      connection: "", //signalr連接
      messages: [] //返回消息
    };
  },
  methods: {
    //給全部發送消息
    sendAll: function() {
      this.connection
        .invoke("SendMessage", this.user, this.message)
        .catch(function(err) {
          return console.error(err);
        });
    },
    //只給自己發送消息
    sendOwn: function() {
      this.connection
        .invoke("SendMessageCaller", this.message)
        .catch(function(err) {
          return console.error(err);
        });
    },
    //系統發送消息
    sendClient: function() {
      this.$http.get("http://localhost:13989/api/test/get").then(resp => {
        console.log(resp);
      });
    }
  },
  created: function() {
    let thisVue = this;
    this.connection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:13989/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
      })
      .configureLogging(signalR.LogLevel.Information)
      .build();
    this.connection.on("ReceiveMessage", function(user, message) {
      thisVue.messages.push({ user, message });
      console.log({ user, message });
    });
    this.connection.on("ReceiveCaller", function(message) {
      let user = "自己"; //這里為了push不報錯,我就弄了一個默認值。
      thisVue.messages.push({ user, message });
      console.log({ user, message });
    });
    this.connection.start();
  }
};
</script>

這樣的話,就能開篇那個效果了。

這里說幾個注意的點,添加控制器之后一定要啟用他,還有路由也要配置,否則你用postman的也是請求不到的,然后就是跨域配置,這些都是實現這個功能不能缺少的配置。

源碼地址:https://github.com/QQ2287991080/SignalRServerAndVueClientDemo

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM