Search code examples
vue.jssignalrvuex

Connect signalr with vue / vuex


I am trying to connect SignalR hub to a Vue component but I fail doing that. i googled "vue with signalr" and real almost every link up to second page. I getting a cors origin, but I dont think that this is the main problem, since my post/get call to web api are working well. c# port number 63213 , client at 8080

I also using vuex and i am wonder if I should connect in at the store. here are code examples. I use vue/vuex with typescript falvor.

  mounted: function() {
    //... under mounted, signalR connection.  i am using import * as signalR from "@aspnet/signalr";  
  this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:63213/ChatHub")
      .build();

    // connecting to the hub
    this.hubConnection
      .start()
      .then(() => console.log("connection started"))
      .catch(err => console.log("connecting hub failed err is : ", err));

    //at the hub there is a function named broadcastMessage, should return string that will be added to an array. should it be at sotr's getter  
    this.connection.on("broadcastMessage", function(msg: string) {
      this.messages.push({ msg });
    });
  },

c#

public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var policy = new CorsPolicy()
            {
                AllowAnyOrigin = true,
                AllowAnyHeader = true,
                AllowAnyMethod = true,
                SupportsCredentials = true
            };

            policy.Origins.Add("http://localhost:8080");

            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
  • pot get to web api are working well.

hub

public class ChatHub : Hub
    {

        public static void SendMessage(string msg)
        {
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
            hubContext.Clients.All.broadcastMessage(msg, " !! !! ");
        }
    }

error is:

Access to XMLHttpRequest at 'http://localhost:63213/ChatHub/negotiate' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

should i pass the hub connention to the store? what am i doing wrong?

thank you.


Solution

  • switched to .core object.

    under "Configure"

    app.UseCors(builder => builder.WithOrigins("http://localhost:8080").AllowAnyMethod().AllowAnyHeader().AllowCredentials());
    
    app.UseSignalR(route => {route.MapHub<UserHub>("/user-hub");} );
    

    under ConfigureServices

    services.AddSignalR();
    services.AddCors();
    

    at vue component (ts)

    created: function() {
        this.$userHub.$on("user-added-event", this.userAddedEvent);
      },
      beforeDestroy: function() {
        //clean SignalR event
        this.$userHub.$off("user-added-event", this.userAddedEvent);
      },
    

    user-hub.js used to handle connection. imported as vue plugin

    import { HubConnectionBuilder, LogLevel } from "@aspnet/signalr";
    export default {
      install(Vue) {
    
        const connection = new HubConnectionBuilder()
          .withUrl(`${Vue.prototype.$http.defaults.baseURL}/user-hub`) 
          .configureLogging(LogLevel.Information)
          .build();
    
    
        const userHub = new Vue();
    
        Vue.prototype.$userHub = userHub;
    
        connection.on("AddUserEvent", (userId, userName) => {
          userHub.$emit("user-added-event", { userId, userName });
        });
    
        // if connection closed, reopen it
        let startedPromise = null;
        function start() {
          startedPromise = connection.start().catch(err => {
            return new Promise((resolve, reject) =>
              setTimeout(
                () =>
                  start()
                    .then(resolve)
                    .catch(reject),
                5000
              )
            );
          });
          return startedPromise;
        }
    
        connection.onclose(() => start());
    
        start();
      }
    };
    

    full project will be uploaded to git.