如何制作一个简单的无服务器 SignalR 应用程序?关于这方面的文档确实很分散,而且似乎都是传统的。 asp 版本一直在说,“别担心这些东西”,这是无服务器所必需的。
这适用于谈判,但之后我错过了什么?对 api 的调用不会到达端点。我只在本地运行这个。这个应用程序确实可以作为响应 http 请求的服务器,不需要 SignalR 的东西,所以我可以访问一些端点。
后端代码:
// This gets hit and succeeds:
[FunctionName("negotiate")]
public static SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
[SignalRConnectionInfo(HubName = "TestHub")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
// This works in an ASP app, but doesn't get hit in Serverless:
public async Task SendMessage(string message)
{
char[] stringArray = message.ToCharArray();
Array.Reverse(stringArray);
string reversedStr = new string(stringArray);
await Clients.All.SendAsync("ReceiveMessage", reversedStr);
}
前端代码:
// All this works for Vue talking to the ASP app, and it hits Negotiate with serverless, but noting else:
const connection = new signalR.HubConnectionBuilder()
//.withUrl("http://localhost:5192/chatHub") //SignalR-POC.ASP
.withUrl("http://localhost:7230/api") //Serverless running locally
.configureLogging(signalR.LogLevel.Information)
.withAutomaticReconnect()
.build();
// Inbound: `connection.on()`s should be registered before `.start` executes
connection.on("ReceiveMessage", (reply) => {
console.log("[SignalR.ReceiveMessage] " + reply);
serverReply.value = reply;
});
async function start() {
try {
await connection.start();
console.log("[SignalR.start] Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
// Outbound
async function sendToServer(){
try {
console.log("[SignalR.SendMessage] " + userInput.value);
await connection.invoke("SendMessage", userInput.value);
} catch (err) {
console.error(err);
}
}
connection.onclose( async () => {
console.log("[SignalR.onclose] Closed.");
await start()
});
// Start the connection.
start();
</script>
<style>
.table2x3{
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.my-button{
grid-column-end: span 2;
margin-top:0.5em;
}
这是我能够在本地运行 Serverless SingnalR api 和客户端并能够访问端点的方式
1。 无服务器 SignalR API:
Azure Functions
并创建项目。HTTP trigger
并提供名称(例如“HttpFunction”)。这是功能代码
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
public static class HttpFunction
{
[FunctionName("SendMessage")]
public static async Task<IActionResult> SendMessage(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
[SignalR(HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string message = req.Query["message"];
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(message))
{
var signalRMessage = new SignalRMessage
{
Target = "newMessage",
Arguments = new object[] { name, message }
};
await signalRMessages.AddAsync(signalRMessage);
return new OkObjectResult($"Message sent to SignalR hub");
}
else
{
return new BadRequestObjectResult("Please pass a name and message in the query string");
}
}
}
2。 无服务器 SignalR 中心: 通过向您的项目添加新类(例如
ChatHub.cs
)来创建新的 SignalR 集线器:
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
public async Task SendMessage(string name)
{
await Clients.All.SendAsync("newMessage", name);
}
}
3.配置SignalR连接字符串:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureSignalRConnectionString": "YourAzureSignalRConnectionString"
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "http://localhost:7071/api/SendMessage" // Add this line to specify allowed origins (e.g., localhost:3000)
}
}
4.客户:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SignalR Client</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.11/signalr.min.js"></script>
</head>
<body>
<h1>SignalR Client</h1>
<input type="text" id="messageInput" placeholder="Enter your name">
<button id="sendMessage">Send</button>
<ul id="messages"></ul>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/api")
.build();
connection.start().catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendMessage").addEventListener("click", function () {
const name = document.getElementById("messageInput").value;
connection.invoke("SendMessage", name).catch(function (err) {
return console.error(err.toString());
});
});
connection.on("newMessage", function (name) {
const li = document.createElement("li");
li.textContent = name;
document.getElementById("messages").appendChild(li);
});
</script>
</body>
</html>
5。运行解决方案 功能触发
结果 使用邮递员 选择发布,粘贴您的 api 并单击发送
传递你的价值观
结果