我正在尝试将使用 SignalR 的应用程序从“基于传统服务器”移动到无服务器 Azure Function 应用程序。我点击 Negotiate 方法没有问题,但我最基本的客户端到服务器方法不会触发。
// Server endpoints...
namespace TooDuh.Serverless.Hubs
{
public class TestHub: ServerlessHub
{
[FunctionName("negotiate")]
public SignalRConnectionInfo Negotiate( [HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req )
{
var claims = GetClaims(req.Headers["Authorization"]);
var connectionInfo = Negotiate( req.Headers["x-ms-signalr-user-id"], claims );
return connectionInfo;
}
[FunctionName("SendMessage")]
public async Task SendMessage(
[SignalRTrigger] InvocationContext invocationContext, string message, ILogger logger)
{
logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
char[] stringArray = message.ToCharArray();
Array.Reverse(stringArray);
string reversedStr = new string(stringArray);
await Clients.All.SendAsync("ReceiveMessage", reversedStr);
}
...
// Client method...
async function sendToServer(){
try {
console.log("[Client.SignalR.SendMessage] " + userInput.value);
await connection.invoke("SendMessage", userInput.value);
} catch (err) {
console.error(err);
}
}
我应该对绑定做一些不同的事情吗?这些文档确实很混乱,但我正在尝试使用 GitHub 上的 AzureSignalR-samples/BidirectionChat 进行工作...当我尝试在本地调试时,这并没有什么更好的效果。
这是我能够使用 SignalR ServerlessHub 方法的方法
第 1 步: 创建 Azure Functions 项目
第 2 步: 确保您的 Azure Functions 项目已正确配置为使用 SignalR。 SignalR 服务连接字符串应存储在您的配置中。 在本地开发的
local.settings.json
文件中
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureSignalRConnectionString": "YOUR_SIGNALR_CONNECTION_STRING"
}
}
第 3 步: 创建您的 SignalR Hub
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
[assembly: FunctionsStartup(typeof(SignalRFunctionApp.Startup))]
namespace SignalRFunctionApp
{
public class TestHub : ServerlessHub
{
[FunctionName("negotiate")]
public SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req)
{
var connectionInfo = Negotiate(req.Headers["x-ms-signalr-user-id"]);
return connectionInfo;
}
[FunctionName("SendMessage")]
public async Task SendMessage(
[SignalRTrigger] InvocationContext invocationContext, string message, ILogger log)
{
log.LogInformation($"Received message: {message} from {invocationContext.ConnectionId}");
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
}
第 4 步: 添加所需的包
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.SignalRService" Version="2.0.0" />
</ItemGroup>
第 5 步: 客户端代码 您可以使用简单的 HTML/JavaScript 客户端连接到您的 SignalR 中心。
<!DOCTYPE html>
<html>
<head>
<title>SignalR Client</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.9/signalr.min.js"></script>
</head>
<body>
<input type="text" id="userInput" />
<button onclick="sendToServer()">Send Message</button>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/api/negotiate")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("ReceiveMessage", (message) => {
console.log("Received message from server: " + message);
});
async function sendToServer() {
const userInput = document.getElementById("userInput");
try {
// Check if the connection is in the "Connected" state
if (connection.state === signalR.HubConnectionState.Connected) {
console.log("[Client.SignalR.SendMessage] " + userInput.value);
await connection.invoke("SendMessage", userInput.value);
} else {
console.error("Connection is not in the 'Connected' state.");
}
} catch (err) {
console.error(err);
}
}
connection.start()
.then(() => {
console.log("Connected to the SignalR hub");
})
.catch((error) => {
console.error(`Error connecting to the hub: ${error}`);
});
</script>
</body>
</html>
验证连接状态:
在调用“SendMessage”方法之前,请确保SignalR连接处于“Connected”状态。您可以使用连接的
state
属性来检查当前状态并确保在发送消息之前已连接
结果