Reputation: 139
I'm trying to send a message using SignalR and Angular, but the API never gets hit on the backend. No status code at all so it never makes it to API endpoint. The hub connection establishes fine so I would think it hits the endpoint automatically when executing this.hubConnection.invoke('NewMessage', message);
but it doesn't seem to work. I'm really new to SignalR so I appreciate any help!
messaging azure function code
module.exports = async function (context, req) {
return {
"target": "newMessage",
"arguments": [ req.body ]
};
};
function.json
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "signalR",
"name": "$return",
"hubName": "chat",
"direction": "out"
}
]
}
angular service
import { Injectable, EventEmitter } from "@angular/core";
import * as signalR from "@aspnet/signalr";
import { SignalViewModel } from "./signal-view-model";
@Injectable({
providedIn: "root"
})
export class SignalRService {
private hubConnection: signalR.HubConnection;
signalReceived = new EventEmitter<SignalViewModel>();
constructor() {
this.buildConnection();
this.startConnection();
}
private buildConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:7070/api")
.build();
};
sendMessage(message: SignalViewModel) {
this.hubConnection.invoke('NewMessage', message);
}
private startConnection = () => {
this.hubConnection
.start()
.then(() => {
console.log("Connection Started...");
this.registerSignalEvents();
})
.catch(err => {
console.log("Error while starting connection: " + err);
//if you get error try to start connection again after 3 seconds.
setTimeout(function () {
this.startConnection();
}, 3000);
});
}
private registerSignalEvents() {
this.hubConnection.on("SignalMessageReceived", (data: SignalViewModel) => {
this.signalReceived.emit(data);
});
}
}
angular component
txtMessage: string = 'd';
uniqueID: string = new Date().getTime().toString();
messages = new Array<SignalViewModel>();
signalRMessage = new SignalViewModel();
sendMessage(): void {
if (this.txtMessage) {
console.log("Executing signalr")
this.signalRMessage = new SignalViewModel();
this.signalRMessage.clientuniqueid = this.uniqueID;
this.signalRMessage.type = "sent";
this.signalRMessage.message = this.txtMessage;
this.signalRMessage.date = new Date();
this.messages.push(this.signalRMessage);
this.signalRService.sendMessage(this.signalRMessage);
this.txtMessage = '';
}
negotiate function
module.exports = async function (context, req, connectionInfo) {
context.res.json(connectionInfo);
};
function.json of negotiate function
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"direction": "in"
}
]
}
Upvotes: 1
Views: 1561
Reputation: 3621
The problem is that you have the "NewMessage"
with the capital "N" on the client side and "newMessage" on the function.
module.exports = async function (context, req) { return { "target": "newMessage", // "n" "arguments": [ req.body ] }; };
sendMessage(message: SignalViewModel) {
this.hubConnection.invoke('NewMessage', message); // "N"
}
Also take a look at this documentation about Azure SignalR Service in Serverless mode. As you can see, if your hub is configured to Serverless mode, you can't call methods from client.
If you're using Azure SignalR Service in Serverless mode, you cannot call hub methods from a client. For more information, see the SignalR Service documentation. Link
Update: Since you are working on Azure Functions and you need to run SignalR on serverless mode, as you can see below you can't invoke hub methods from the client.
Upvotes: 1