quangdaon / vue-signalr

SignalR plugin for Vue
MIT License
18 stars 2 forks source link

Connecting Signal R on a vue front end to asp.net core 6 web api back end #32

Open AppyCat opened 2 years ago

AppyCat commented 2 years ago

Hi, I'm new to asp.net core 6 and have successfully setup a Signal R connection within a self contained net core 6 web app.

Now I'm trying to separate it into a back end net core 6 web api connecting with a Vue front end app coded in Nuxt with the Quasar framework.

The websocket connection is being made to the ChatHub, and it appears the message is being sent. And it appears CORS is working fine.

However I'm not receiving it when it's sent out to all connected Vue clients. It's probably something simple off in the way I'm wiring the code. Here's how it looks so far:

import { ref } from 'vue'; import axios from 'axios'; import { useSignalR } from '@dreamonkey/vue-signalr'; import { inject } from 'vue';

setup () { const signalr = useSignalR();

let user = "John Doe";
let message = "How's it going?";

signalr.invoke('SendMessage', user, message);

signalr.on('MessageReceived', ({ user, message }) => {
  this.user = user;
  this.message = message
});

return {
  date: ref('2022/02/15'),
  slide: ref('style')
}

}

Appreciate any pointers on where the logic may be off above. Thanks.

This is the back end ChatHub.cs

using Microsoft.AspNetCore.SignalR;

namespace chat_api.Hubs;

public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } }

And in program.cs

app.MapHub("/chatHub");

quangdaon commented 2 years ago

Hello! It looks like you have a discrepancy between your message name. You're broadcasting an event called ReceiveMessage, but listening for one called MessageReceived. The names need to match exactly.

AppyCat commented 2 years ago

Thank you, that worked and messages are being received by all clients :)

Now only remaining part is how do you render in the view template the data received in the ReceiveMessage?

quangdaon commented 2 years ago

I just noticed that your import references @dreamonkey/vue-signalr instead of @quangdao/vue-signalr. If that's the package you're using and this doesn't help, you'll want to recreate this issue at https://github.com/dreamonkey/vue-signalr instead.

With either package, you should be able to set the response to your component state. That can change depending on what "style" you're using. With the Composition API in Single File Components, one option is something like this:

<template>
 <p>{{ message }}</p>
</template>

<script>
/* import ... */

export default {
  setup() {
    const signalr = useSignalR();
    const message = ref(''); // Create a ref aka a reactive property

    signalr.invoke('SendMessage', { message });

    signalr.on('MessageReceived', (response) => {
      message.value = response.message; // Set the value of the message property to the response
    });

    return { message }; // Expose the property to the view template
  }
};
</script>
p10tyr commented 1 year ago

Hello why is this sample different than on Wiki. I only ask because I have a problem

const SendMessage: HubCommandToken<MyObject> = 'SendMessage'; cannot find "HubCommandToken" name when trying to compile.

But here you just use the string "SendMessage" ?

quangdaon commented 1 year ago

Hi, sorry for the slow response. This package accepts both versions, but using a raw string value will forego type-checking on the message content (on Commands, e.g. invoke) or response (on Events, e.g. on).

Are you importing HubCommandToken in the code that's failing to compile?