You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:35:23