• 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

     
  • 相关阅读:
    判断鼠标点击在div外时,更改背景图片
    CSS--border边框颜色渐变
    实验一:Java开发环境的熟悉
    实验楼第四次试验报告
    实验楼第三次试验报告
    实验楼第二次试验报告
    实验楼第一次试验报告
    c++程序设计中的函数重载
    C++中,new/delete和malloc/free的区别
    继承和多态二:虚析构函数
  • 原文地址:https://www.cnblogs.com/aqgy12138/p/12882511.html
Copyright © 2020-2023  润新知