azure 使用_如何使用JavaScript在Azure上开始使用SignalR

azure 使用

The other day, some fine developers at my company were getting ready to roll out a status update page. We'd tested it extensively but now we were about to put it out at scale.

前几天,我公司的一些优秀开发人员正准备推出状态更新页面。 我们已经对其进行了广泛的测试,但是现在我们将要大规模推广它。

I was worried about its dependency on an API server that had been acting up recently. We haven't determined the root cause of our problems on the API side, and this application uses polling - that is, it constantly asks the API for new data. If that API goes down, it takes our app with it and the increased load from our app might exacerbate the problems we're seeing.

我担心它对最近运行的API服务器的依赖性。 在API方面,我们尚未确定问题的根本原因,此应用程序使用轮询-也就是说,它不断向API请求新数据。 如果该API出现故障,它将带走我们的应用程序,并且应用程序增加的负载可能会加剧我们所看到的问题。

Tourists in Ireland, perhaps waiting for a message

One way to step away from polling is to integrate SignalR, a persistent connection tool that uses websockets and related technologies to allow servers to push updates to clients.

摆脱轮询的一种方法是集成SignalRSignalR是一种持久连接工具,使用websocket和相关技术来允许服务器更新送到客户端。

The technology is written in .NET, and most of the documentation you will find around the web is using C#. This tutorial will cover a basic JavaScript implementation.

该技术是用.NET编写的,并且在网络上可以找到的大多数文档都使用C#。 本教程将介绍基本JavaScript实现。

它有什么作用? (What does it do?)

Open-sourced SignalR creates a persistent connection between a client and server. It uses websockets first, then longpolling and other technologies when websockets are unavailable.

开源的 SignalR在客户端和服务器之间创建持久连接。 当网络套接字不可用时,它首先使用网络套接字,然后使用长轮询和其他技术。

Once the client and server have created a connection, SignalR can be used to "broadcast" messages to the client. When the client receives those messages, it can perform functions like updating a store.

客户端和服务器创建连接后,SignalR可用于向客户端“广播”消息。 当客户端收到这些消息时,它可以执行诸如更新商店之类的功能。

The most common example given for websockets is a chat app - new data must be shown to the user without her needing to refresh the page. But if your server gets any updates about changing data that you need to show to a client, this might be the service for you.

针对websocket的最常见示例是聊天应用程序-必须向用户显示新数据,而无需刷新页面。 但是,如果您的服务器获得了有关更改数据的任何更新(需要向客户端显示),则这可能是为您提供的服务。

Azure平台上的SignalR (SignalR on the Azure platform)

Perhaps because it was developed by Microsoft, SignalR has a very clean integration on the Azure cloud platform. Like other function apps, you'll create an "in" trigger and an "out" binding for broadcasting messages.

也许是因为它是由Microsoft开发的,SignalR在Azure云平台上具有非常干净的集成。 像其他功能应用程序一样,您将创建“输入”触发器和“输出”绑定以广播消息。

费用 (Costs)

Because I was the first to look at this technology at scale at my company, I had to dig in a little about costs for this service. Azure charges about $50/month for one "unit" of SignalR service - 1000 simultaneous connections and one million messages a day. There is also a free service for those playing around or small businesses.

因为我是第一个在公司中大规模研究该技术的人,所以我不得不深入了解这项服务的成本。 Azure每月为一个“单元” SignalR服务收取约50美元/月的费用-每天1000个同时连接和一百万条消息。 还为那些玩耍的人或小型企业提供免费服务。

It was really good I dug into those numbers, as you'll see a little below.

我仔细研究了这些数字,真的很好,因为您会在下面看到一些内容。

创建一个SignalR集线器 (Create a SignalR hub)

Let's get started. We'll need a SignalR hub, two function apps, and client code to add to our web app.

让我们开始吧。 我们需要一个SignalR集线器,两个功能应用程序和客户端代码来添加到我们的Web应用程序中。

Go to SignalR -> Add and fill out your details. It takes a second for the worker to build your service. Make sure you give the service a decent resource name, as you'll be using it with the rest of your apps. Also grab Keys -> Connection String for use in our binding.

转到SignalR->添加并填写您的详细信息。 工作人员需要一秒钟的时间来建立您的服务。 确保为服务提供适当的资源名称,因为它将与其他应用程序一起使用。 还要获取Keys-> Connection String以便在我们的绑定中使用。

Setting up SignalR on Azure

创建您的功能应用程序以发送SignalR消息 (Create your function app for sending SignalR messages)

Because we're working with Azure, we're going to be creating function apps to interface with SignalR. I wrote a getting-started blog post about Azure function apps a little while ago.

因为我们正在使用Azure,所以我们将创建功能应用程序以与SignalR交互。 不久前,我写了一篇有关Azure函数应用程序的入门博客文章

This tutorial assumes you already know how to work with function apps. Naturally you can work with these libraries without the binding magic, but you'll have to do your own translation of the .NET code!

本教程假定您已经知道如何使用功能应用程序。 自然,您可以在没有绑定魔术的情况下使用这些库,但是您必须自己翻译.NET代码!

连接应用 (The connection app)

The first thing we need is a way for clients to request permission to connect to our SignalR service. The code for this function couldn't be more basic:

我们需要的第一件事是客户端请求权限以连接到SignalR服务的方式。 此函数的代码再简单不过了:

module.exports = function (context, _req, connectionInfo) {
  context.res = { body: connectionInfo }
  context.done()
}

The magic all happens in the bindings, where we pull in our SignalR service. The trigger is an HTTP request that our client can call.

魔术全部发生在绑定中,我们在其中引入了SignalR服务。 触发器是我们的客户端可以调用的HTTP请求。

{
  "bindings": [
      {
          "authLevel": "function",
          "type": "httpTrigger",
          "direction": "in",
          "name": "req",
          "methods": ["get"]
      },
      {
          "type": "signalRConnectionInfo",
          "name": "connectionInfo",
          "hubName": "your-signalr-service-name",
          "connectionStringSetting": "connection-string",
          "direction": "in"
      }
  ]
}

客户端代码 (The client code)

To access this method, our client will call:

要访问此方法,我们的客户将调用:

import * as signalR from '@microsoft/signalr'

const { url: connectionUrl, accessToken } = await axios
  .get(url-to-your-connection-app)
  .then(({ data }) => data)
  .catch(console.error)

Our function app will return a url and accessToken, which we can then use to connect to our SignalR service. Note that we created the binding with the hubName of our SignalR service - that means you could have multiple connections to different hubs in one client.

我们的函数应用程序将返回urlaccessToken ,然后我们可以使用它们来连接到我们的SignalR服务。 请注意,我们使用SignalR服务的hubName创建了绑定-这意味着您可以在一个客户端中具有到不同集线器的多个连接。

广播服务 (The broadcasting service)

Now we are ready to start sending messages. Again we'll start with the function app. It takes in a trigger and puts out a SignalR message.

现在我们准备开始发送消息。 再次,我们将从功能应用程序开始。 它接受触发器并发出SignalR消息。

A trigger could be another using posting a message, an event from an event hub, or any other trigger Azure supports. I need to trigger off database changes.

触发器可以是另一个触发器,可以使用发布消息,来自事件中心的事件或Azure支持的任何其他触发器。 我需要触发数据库更改。

{
  "bindings": [
      {
          "type": "cosmosDBTrigger",
          "name": "documents",
          "direction": "in",
          [...]
      },
      {
        "type": "signalR",
        "name": "signalRMessages",
        "hubName": "your-signalr-service-name",
        "connectionStringSetting": "connection-string",
        "direction": "out"
      }
  ]
}

And the code. Again, dead simple.

和代码。 再次,死得很简单。

module.exports = async function (context, documents) {
  const messages = documents.map(update => {
    return {
      target: 'statusUpdates',
      arguments: [update]
    }
  })
  context.bindings.signalRMessages = messages
}

SignalR messages take a target and arguments object. Once your triggers start firing, that's everything you need to get started with SignalR on the server! Microsoft has made all of this very easy for us.

SignalR消息采用targetarguments对象。 触发器开始触发后,这就是在服务器上开始使用SignalR所需的一切! Microsoft对我们而言,使所有这些事情变得非常容易。

客户端代码 (The client code)

On the client side, things are a little more complex, but not unmanageable. Here's the rest of the client code:

在客户端,情况有些复杂,但并非难以管理。 这是其余的客户端代码:

const connection = new signalR.HubConnectionBuilder()
  .withUrl(connectionUrl, { accessTokenFactory: () => accessToken })
  // .configureLogging(signalR.LogLevel.Trace)
  .withAutomaticReconnect()
  .build()

connection.on('statusUpdates', data => {
  // do something with the data you get from SignalR
})
connection.onclose(function() {
  console.log('signalr disconnected')
})
connection.onreconnecting(err =>
  console.log('err reconnecting  ', err)
)

connection
  .start()
  .then(res => // Potential to do something on initial load)
  .catch(console.error)

We consume the connectionUrl and accessToken we received from the connect function earlier, then build our connection using those values.

我们将消耗先前从connect函数接收到的connectionUrlaccessToken ,然后使用这些值建立连接。

Then we listen to messages with the shared key (for me, it's statusUpdates), and provide handlers for close and reconnecting functions.

然后,我们使用共享密钥(对于我来说是statusUpdates )来监听消息,并提供用于关闭和重新连接功能的处理程序。

Finally, we start the connection. Here we can provide an initial load function. I needed one to fetch initial data to show current status. If you are building a chat app, you might need to fetch initial messages here.

最后,我们开始连接。 在这里,我们可以提供初始加载函数。 我需要一个来获取初始数据以显示当前状态。 如果要构建聊天应用程序,则可能需要在此处获取初始消息。

This is (almost, maybe) everything you need to get started in JavaScript with SignalR on Azure!

这(几乎,也许)是在Azure上使用SignalR在JavaScript中入门所需的一切!

用户范围 (Scoping by user)

But maybe you, like me, need to send a lot of messages to a lot of users.

但是也许您和我一样需要向很多用户发送很多消息。

When I first put this into production, on a sub-set of users, I was blasting every connection with every single update. Because the client code can scope the messages it listens to, I used something like statusUpdates-${userId} so that the client would only see his own updates.

当我第一次将它投入生产时,是针对用户的子集的,每次爆炸都会爆炸每个连接。 因为客户端代码可以确定其侦听的消息的范围,所以我使用了诸如statusUpdates-${userId}以便客户端只能看到自己的更新。

That could work just fine if you have very low volume, and the more general one is great if everybody in your system needs the same message. But the status I work with is particular to an individual.

如果您的交易量很小,那可能会很好,而如果您系统中的每个人都需要相同的消息,那比较普遍。 但是我所处的地位是个人所特有的。

800,000 SignalR messages sent from Azure platform

Remember how Azure charges per "unit" and each unit has one million messages? I hit that during a few hours of testing this during a not-busy time.

还记得Azure如何为每个“单位”收费,每个单位有一百万条消息吗? 我在一个不忙的时间内进行了几个小时的测试,就发现了这一点。

Azure counts each message SignalR has to send as one message. That is, if five connections are hooked up to your hub and you send ten messages, that counts as 50, not 10. This was a surprise to me, and also required a couple more hours of research.

Azure将SignalR必须发送的每条消息视为一条消息。 就是说,如果您的集线器连接了五个连接,并且您发送了十条消息,则该数目等于50,而不是10。这让我感到惊讶,并且还需要花费更多的时间进行研究。

We can scope our SignalR function code to send only to certain users. First, we update the connection app to accept userId as a query param:

我们可以将SignalR功能代码的范围限定为仅发送给某些用户。 首先,我们更新连接应用程序以接受userId作为查询参数:

{
          "type": "signalRConnectionInfo",
          "name": "connectionInfo",
          "userId": "{userId}",
          "hubName": "your-signalr-service-name",
          "connectionStringSetting": "connection-string",
          "direction": "in"
      }

Then we update the broadcasting function to send only to that user:

然后,我们将广播功能更新为仅发送给该用户:

const messages = documents.map(update => {
  return {
    target: 'statusUpdates',
    userId: update.user.id,
    arguments: [update]
  }
})

The broadcasting service won't know who has connected, so you'll need to trigger it with something that has access to a unique ID that the client will also have access to.

广播服务不知道是谁连接的,因此您需要使用可以访问客户端也会访问的唯一ID的东西来触发它。

The client code simply passes in the userId as a query param:

客户端代码只是将userId作为查询参数传递:

const { url: connectionUrl, accessToken } = await axios
  .get(`${url-to-your-connection-app}&userId=${userId}`)
  .then(({ data }) => data)
  .catch(console.error)

I swear to you, the only place on the entire internet I found to let me know how to request a connection using the userId was an answer on this Stack Overflow question.

我向你发誓,我发现整个互联网上唯一让我知道如何使用userId请求连接的地方就是这个Stack Overflow问题的答案。

The internet is amazing, and JavaScript Azure docs are hard to come by.

互联网是惊人的,并且很难获得JavaScript Azure文档。

资源资源 (Resources)

This post originally appeared on wilkie.tech.

该帖子最初出现在wilkie.tech上

翻译自: https://www.freecodecamp.org/news/getting-started-with-signalr-in-azure-using-javascript/

azure 使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值