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

 

 
posted @ 2020-05-13 16:59  飞天猪皮怪  阅读(3178)  评论(0编辑  收藏  举报