如何在Serverless JavaScript中映射SignalR连接与用户ID?
解决方案:自定义用户ID与SignalR连接关联
要在不依赖Azure App Service认证的情况下,将客户端SignalR连接与自定义用户ID绑定,只需修改客户端连接逻辑和Azure Function的negotiate函数即可,具体步骤如下:
1. 客户端传递用户ID到SignalR连接
在客户端发起SignalR连接时,通过查询参数或自定义请求头传递已有的用户ID(从你的自定义认证逻辑中获取,比如登录后存储的用户ID):
// 从自定义认证逻辑获取当前用户ID const currentUserId = "user_12345"; const connection = new signalR.HubConnectionBuilder() .withUrl(`${apiBaseUrl}/api`, { // 方式1:通过查询参数传递用户ID(推荐,简单直接) queryParams: { userId: currentUserId }, // 方式2:如果用自定义认证头传递,可替换为以下配置 // headers: { // 'Authorization': `Bearer ${你的自定义认证Token}`, // 'X-User-ID': currentUserId // } }) .build(); connection.on('newMessage', (msg) => { console.log(msg); }); connection.start().catch(console.error);
2. 修改Azure Function的Negotiate函数,绑定用户ID
默认的Negotiate函数需要修改,从客户端请求中提取用户ID,并将其注入到SignalR连接信息中,这样SignalR服务就会将该连接与指定用户ID关联:
module.exports = async function (context, req, connectionInfo) { // 从查询参数获取用户ID(对应客户端传递的方式) const userId = req.query.userId; // 如果用自定义请求头传递,改为: // const userId = req.headers['x-user-id']; // 如果从自定义Token解析,可使用JWT库解析Token中的用户ID: // const token = req.headers.authorization?.split(' ')[1]; // const decoded = require('jsonwebtoken').verify(token, '你的Token密钥'); // const userId = decoded.userId; // 将用户ID绑定到SignalR连接信息 connectionInfo.userId = userId; context.res = { body: connectionInfo }; };
确保Negotiate函数的function.json配置包含正确的SignalR连接信息输入绑定:
{ "bindings": [ { "authLevel": "anonymous", "type": "httpTrigger", "direction": "in", "name": "req", "methods": ["post"] }, { "type": "signalRConnectionInfo", "name": "connectionInfo", "hubName": "你的Hub名称", "connectionStringSetting": "AzureSignalRConnectionString", "direction": "in" }, { "type": "http", "direction": "out", "name": "res" } ] }
3. 发送指定用户的消息
此时你的sendMessage函数可以直接按原示例代码运行,指定目标用户ID即可向对应客户端发送消息:
module.exports = async function (context, req) { context.bindings.signalRMessages = [{ "userId": req.body.targetUserId, // 从请求参数获取目标用户ID "target": "newMessage", "arguments": [req.body.messageContent] }]; context.res = { status: 200, body: "消息已成功发送至指定用户" }; };
原理说明
客户端在Negotiate阶段传递用户ID,服务端将该ID注入到SignalR连接凭证中,SignalR服务会自动维护用户ID与连接的映射关系。当调用sendMessage指定userId时,SignalR会精准推送消息给所有关联该用户ID的客户端连接。
内容的提问来源于stack exchange,提问作者Mohammed Magdy
相关产品推荐
相关产品推荐

